gps-plus-slam-app-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +222 -0
  3. package/dist/alignment-lerper-D9BeDwZX.d.ts +29 -0
  4. package/dist/app-selectors-DyMzxCEC.d.ts +140 -0
  5. package/dist/ar/camera-blit-capture.d.ts +2 -0
  6. package/dist/ar/camera-blit-capture.js +253 -0
  7. package/dist/ar/capture-failure-tracker.d.ts +2 -0
  8. package/dist/ar/capture-failure-tracker.js +45 -0
  9. package/dist/ar/chromium-camera-access-workaround.d.ts +2 -0
  10. package/dist/ar/chromium-camera-access-workaround.js +32 -0
  11. package/dist/ar/depth-sampler.d.ts +3 -0
  12. package/dist/ar/depth-sampler.js +147 -0
  13. package/dist/ar/image-capture.d.ts +2 -0
  14. package/dist/ar/image-capture.js +152 -0
  15. package/dist/ar/index.d.ts +12 -0
  16. package/dist/ar/index.js +12 -0
  17. package/dist/ar/replay-scene.d.ts +2 -0
  18. package/dist/ar/replay-scene.js +325 -0
  19. package/dist/ar/scene-node-names.d.ts +2 -0
  20. package/dist/ar/scene-node-names.js +16 -0
  21. package/dist/ar/tracking-state.d.ts +2 -0
  22. package/dist/ar/tracking-state.js +164 -0
  23. package/dist/ar/webxr-session.d.ts +4 -0
  24. package/dist/ar/webxr-session.js +890 -0
  25. package/dist/ar/xr-camera-texture.d.ts +2 -0
  26. package/dist/ar/xr-camera-texture.js +39 -0
  27. package/dist/ar/xr-error-handler.d.ts +2 -0
  28. package/dist/ar/xr-error-handler.js +37 -0
  29. package/dist/ar-types-B-ORgk6Z.d.ts +82 -0
  30. package/dist/camera-blit-capture-DHuyrrxr.d.ts +108 -0
  31. package/dist/camera-follower-BMqPddxx.d.ts +29 -0
  32. package/dist/capture-failure-tracker-2Q6oI2uQ.d.ts +52 -0
  33. package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +61 -0
  34. package/dist/community-license-key-ChZLCJyO.d.ts +21 -0
  35. package/dist/concurrency-p6gB30fT.d.ts +24 -0
  36. package/dist/css3d-renderer-manager-rgLMVAvd.d.ts +23 -0
  37. package/dist/depth-sampler-BNCtnEoP.d.ts +108 -0
  38. package/dist/failure-tracker-1sQ_Cgyw.d.ts +49 -0
  39. package/dist/file-system-BsQgYCU3.d.ts +128 -0
  40. package/dist/file-system-utils-5cWO8Xyv.d.ts +24 -0
  41. package/dist/format-file-size-onGq0k1Q.d.ts +24 -0
  42. package/dist/fused-path-DtqCSqJh.d.ts +25 -0
  43. package/dist/geo-types-Xx-LVcnw.d.ts +29 -0
  44. package/dist/gps-Ddzr2KlX.d.ts +54 -0
  45. package/dist/gps-compass-cubes-C-6JEnpR.d.ts +22 -0
  46. package/dist/gps-error-handler-VPuNOuf8.d.ts +40 -0
  47. package/dist/gps-event-markers-DpEy2qRd.d.ts +67 -0
  48. package/dist/h3-ref-point-CFhayNSZ.d.ts +59 -0
  49. package/dist/image-capture-2pKjYUS6.d.ts +130 -0
  50. package/dist/index.d.ts +56 -0
  51. package/dist/index.js +61 -0
  52. package/dist/leaflet-map-overlay-CvfQXTye.d.ts +114 -0
  53. package/dist/lerp-utils-87NWjUOD.d.ts +20 -0
  54. package/dist/licensing/community-license-key.d.ts +2 -0
  55. package/dist/licensing/community-license-key.js +21 -0
  56. package/dist/licensing/index.d.ts +2 -0
  57. package/dist/licensing/index.js +2 -0
  58. package/dist/list-formatter-DKQQVLcl.d.ts +14 -0
  59. package/dist/logger-B81iwxx0.d.ts +74 -0
  60. package/dist/map-overlay-DuiZuCTx.d.ts +153 -0
  61. package/dist/null-storage-backend-CsWvQwN8.d.ts +11 -0
  62. package/dist/opfs-storage-ChOzF_Wp.d.ts +181 -0
  63. package/dist/opfs-storage-backend-CVcmfJHN.d.ts +11 -0
  64. package/dist/permission-checker-jO2ziCWC.d.ts +146 -0
  65. package/dist/persistence-middleware-DrptY02i.d.ts +31 -0
  66. package/dist/recorder-slice-fcwAXrsh.d.ts +35 -0
  67. package/dist/recording-coordinator-DzflP07_.d.ts +81 -0
  68. package/dist/recording-options-BYUFX8iU.d.ts +166 -0
  69. package/dist/recording-replayer-oOzPITrd.d.ts +32 -0
  70. package/dist/ref-point-importer-B_wn5ABk.d.ts +62 -0
  71. package/dist/ref-point-loader-Pt1smgHS.d.ts +117 -0
  72. package/dist/ref-points/h3-ref-point.d.ts +2 -0
  73. package/dist/ref-points/h3-ref-point.js +74 -0
  74. package/dist/ref-points/index.d.ts +2 -0
  75. package/dist/ref-points/index.js +2 -0
  76. package/dist/ref-points-slice-tC-Wd6XJ.d.ts +48 -0
  77. package/dist/reference-points-CFWy8_wj.d.ts +68 -0
  78. package/dist/replay-engine-DuX316ae.d.ts +103 -0
  79. package/dist/replay-scene-DtUm6bsr.d.ts +109 -0
  80. package/dist/routing-slice-BlHTM8eh.d.ts +23 -0
  81. package/dist/scene-node-names-DPsaE2z3.d.ts +14 -0
  82. package/dist/sensors/gps-error-handler.d.ts +2 -0
  83. package/dist/sensors/gps-error-handler.js +53 -0
  84. package/dist/sensors/gps.d.ts +2 -0
  85. package/dist/sensors/gps.js +93 -0
  86. package/dist/sensors/index.d.ts +4 -0
  87. package/dist/sensors/index.js +4 -0
  88. package/dist/sensors/permission-checker.d.ts +2 -0
  89. package/dist/sensors/permission-checker.js +397 -0
  90. package/dist/state/app-selectors.d.ts +2 -0
  91. package/dist/state/app-selectors.js +35 -0
  92. package/dist/state/index.d.ts +17 -0
  93. package/dist/state/index.js +13 -0
  94. package/dist/state/persistence-middleware.d.ts +2 -0
  95. package/dist/state/persistence-middleware.js +71 -0
  96. package/dist/state/recorder-slice.d.ts +2 -0
  97. package/dist/state/recorder-slice.js +47 -0
  98. package/dist/state/recording-coordinator.d.ts +2 -0
  99. package/dist/state/recording-coordinator.js +150 -0
  100. package/dist/state/recording-options.d.ts +2 -0
  101. package/dist/state/recording-options.js +192 -0
  102. package/dist/state/recording-replayer.d.ts +2 -0
  103. package/dist/state/recording-replayer.js +39 -0
  104. package/dist/state/ref-points-slice.d.ts +2 -0
  105. package/dist/state/ref-points-slice.js +44 -0
  106. package/dist/state/replay-engine.d.ts +2 -0
  107. package/dist/state/replay-engine.js +230 -0
  108. package/dist/state/routing-slice.d.ts +2 -0
  109. package/dist/state/routing-slice.js +13 -0
  110. package/dist/state/store-subscribers.d.ts +3 -0
  111. package/dist/state/store-subscribers.js +97 -0
  112. package/dist/state/store.d.ts +9 -0
  113. package/dist/state/store.js +71 -0
  114. package/dist/state/subscribe-to-selector.d.ts +2 -0
  115. package/dist/state/subscribe-to-selector.js +26 -0
  116. package/dist/storage/file-system-utils.d.ts +2 -0
  117. package/dist/storage/file-system-utils.js +31 -0
  118. package/dist/storage/file-system.d.ts +2 -0
  119. package/dist/storage/file-system.js +229 -0
  120. package/dist/storage/index.d.ts +11 -0
  121. package/dist/storage/index.js +10 -0
  122. package/dist/storage/null-storage-backend.d.ts +2 -0
  123. package/dist/storage/null-storage-backend.js +8 -0
  124. package/dist/storage/opfs-storage-backend.d.ts +2 -0
  125. package/dist/storage/opfs-storage-backend.js +15 -0
  126. package/dist/storage/opfs-storage.d.ts +2 -0
  127. package/dist/storage/opfs-storage.js +242 -0
  128. package/dist/storage/ref-point-importer.d.ts +2 -0
  129. package/dist/storage/ref-point-importer.js +163 -0
  130. package/dist/storage/ref-point-loader.d.ts +2 -0
  131. package/dist/storage/ref-point-loader.js +248 -0
  132. package/dist/storage/ref-point-recovery.d.ts +28 -0
  133. package/dist/storage/ref-point-recovery.js +159 -0
  134. package/dist/storage/storage-backend.d.ts +2 -0
  135. package/dist/storage/storage-backend.js +1 -0
  136. package/dist/storage/zip-export.d.ts +2 -0
  137. package/dist/storage/zip-export.js +214 -0
  138. package/dist/storage/zip-reader.d.ts +2 -0
  139. package/dist/storage/zip-reader.js +190 -0
  140. package/dist/storage-backend-BcEItnFr.d.ts +20 -0
  141. package/dist/store-C7PKOj8S.d.ts +96 -0
  142. package/dist/store-subscribers-CuoIzB5T.d.ts +77 -0
  143. package/dist/subscribe-to-selector-UTZ0KkAc.d.ts +26 -0
  144. package/dist/test-utils/browser-mocks.d.ts +294 -0
  145. package/dist/test-utils/browser-mocks.js +568 -0
  146. package/dist/test-utils/zip-round-trip-helpers.d.ts +60 -0
  147. package/dist/test-utils/zip-round-trip-helpers.js +207 -0
  148. package/dist/three-dispose-CCBHjE_a.d.ts +30 -0
  149. package/dist/tracking-state-B9QfuZCg.d.ts +101 -0
  150. package/dist/types/ar-types.d.ts +2 -0
  151. package/dist/types/ar-types.js +1 -0
  152. package/dist/types/geo-types.d.ts +2 -0
  153. package/dist/types/geo-types.js +1 -0
  154. package/dist/types/index.d.ts +3 -0
  155. package/dist/types/index.js +1 -0
  156. package/dist/utils/concurrency.d.ts +2 -0
  157. package/dist/utils/concurrency.js +40 -0
  158. package/dist/utils/failure-tracker.d.ts +2 -0
  159. package/dist/utils/failure-tracker.js +48 -0
  160. package/dist/utils/format-file-size.d.ts +2 -0
  161. package/dist/utils/format-file-size.js +41 -0
  162. package/dist/utils/fused-path.d.ts +2 -0
  163. package/dist/utils/fused-path.js +44 -0
  164. package/dist/utils/index.d.ts +7 -0
  165. package/dist/utils/index.js +7 -0
  166. package/dist/utils/list-formatter.d.ts +2 -0
  167. package/dist/utils/list-formatter.js +17 -0
  168. package/dist/utils/logger.d.ts +2 -0
  169. package/dist/utils/logger.js +226 -0
  170. package/dist/vis-colors-Qi2vlRGt.d.ts +63 -0
  171. package/dist/visualization/alignment-lerper.d.ts +2 -0
  172. package/dist/visualization/alignment-lerper.js +68 -0
  173. package/dist/visualization/camera-follower.d.ts +2 -0
  174. package/dist/visualization/camera-follower.js +51 -0
  175. package/dist/visualization/css3d-renderer-manager.d.ts +2 -0
  176. package/dist/visualization/css3d-renderer-manager.js +41 -0
  177. package/dist/visualization/gps-compass-cubes.d.ts +2 -0
  178. package/dist/visualization/gps-compass-cubes.js +129 -0
  179. package/dist/visualization/gps-event-markers.d.ts +2 -0
  180. package/dist/visualization/gps-event-markers.js +159 -0
  181. package/dist/visualization/index.d.ts +12 -0
  182. package/dist/visualization/index.js +12 -0
  183. package/dist/visualization/leaflet-map-overlay.d.ts +2 -0
  184. package/dist/visualization/leaflet-map-overlay.js +313 -0
  185. package/dist/visualization/lerp-utils.d.ts +2 -0
  186. package/dist/visualization/lerp-utils.js +22 -0
  187. package/dist/visualization/map-overlay.d.ts +2 -0
  188. package/dist/visualization/map-overlay.js +241 -0
  189. package/dist/visualization/reference-points.d.ts +2 -0
  190. package/dist/visualization/reference-points.js +160 -0
  191. package/dist/visualization/three-dispose.d.ts +2 -0
  192. package/dist/visualization/three-dispose.js +55 -0
  193. package/dist/visualization/vis-colors.d.ts +2 -0
  194. package/dist/visualization/vis-colors.js +74 -0
  195. package/dist/webxr-session-COlSrXdL.d.ts +316 -0
  196. package/dist/xr-camera-texture-BbukNE79.d.ts +53 -0
  197. package/dist/xr-error-handler-DTHfmvrl.d.ts +24 -0
  198. package/dist/zip-export-Rtpi75JJ.d.ts +87 -0
  199. package/dist/zip-reader-D7pkpX8K.d.ts +97 -0
  200. package/package.json +104 -0
@@ -0,0 +1,2 @@
1
+ import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-BbukNE79.js";
2
+ export { CameraTextureResult, RendererLike, XRCameraLike, acquireCameraTexture };
@@ -0,0 +1,39 @@
1
+ import { createLogger } from "../utils/logger.js";
2
+ //#region ../src/ar/xr-camera-texture.ts
3
+ const log = createLogger("XRCameraTexture");
4
+ /**
5
+ * Acquire the camera texture for the current XR frame using Three.js's
6
+ * built-in getCameraTexture() API, paired with native camera dimensions.
7
+ *
8
+ * Three.js internally:
9
+ * 1. Creates XRWebGLBinding (lazy, one per session)
10
+ * 2. Calls glBinding.getCameraImage(camera) each frame
11
+ * 3. Wraps in ExternalTexture (sourceTexture = native WebGLTexture)
12
+ * 4. Caches per xrCamera in cameraAccessTextures map
13
+ *
14
+ * This function adds the native camera dimensions (width/height) needed
15
+ * for dynamic render target sizing in the blit capture pipeline.
16
+ *
17
+ * Must be called within the XR animation frame callback.
18
+ *
19
+ * @param renderer - The Three.js WebGLRenderer
20
+ * @param xrCamera - The XRCamera from XRView.camera, or null if unavailable
21
+ * @returns CameraTextureResult, or null if acquisition fails
22
+ */
23
+ function acquireCameraTexture(renderer, xrCamera) {
24
+ if (!xrCamera) return null;
25
+ try {
26
+ const texture = renderer.xr.getCameraTexture(xrCamera);
27
+ if (!texture) return null;
28
+ return {
29
+ texture,
30
+ width: xrCamera.width,
31
+ height: xrCamera.height
32
+ };
33
+ } catch (error) {
34
+ log.error("Failed to acquire camera texture:", error);
35
+ return null;
36
+ }
37
+ }
38
+ //#endregion
39
+ export { acquireCameraTexture };
@@ -0,0 +1,2 @@
1
+ import { n as XR_ERROR_MESSAGE_UNKNOWN, r as getXrErrorMessage, t as XR_ERROR_MESSAGES } from "../xr-error-handler-DTHfmvrl.js";
2
+ export { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage };
@@ -0,0 +1,37 @@
1
+ //#region ../src/ar/xr-error-handler.ts
2
+ /**
3
+ * WebXR Error Handler
4
+ *
5
+ * Provides user-facing error messages for WebXR session failures.
6
+ * Separates error handling logic from AR module for testability.
7
+ */
8
+ /**
9
+ * Known WebXR error types and their user-friendly messages.
10
+ */
11
+ const XR_ERROR_MESSAGES = {
12
+ NotSupportedError: "AR not supported on this device. Please ensure ARCore (Android) or ARKit (iOS) is installed.",
13
+ SecurityError: "Camera permission denied. Allow camera access to use AR features.",
14
+ InvalidStateError: "AR session already active. Please close other AR apps and try again.",
15
+ NotAllowedError: "AR access not allowed. Check browser permissions for this site."
16
+ };
17
+ /**
18
+ * Default message for unknown error types.
19
+ */
20
+ const XR_ERROR_MESSAGE_UNKNOWN = "Failed to start AR session. Check device compatibility and permissions.";
21
+ /**
22
+ * Get a user-friendly error message from a WebXR session error.
23
+ *
24
+ * @param error - The error thrown by navigator.xr.requestSession
25
+ * @returns A user-friendly error message
26
+ */
27
+ function getXrErrorMessage(error) {
28
+ if (error instanceof DOMException) return XR_ERROR_MESSAGES[error.name] ?? "Failed to start AR session. Check device compatibility and permissions.";
29
+ if (error instanceof Error) {
30
+ const msg = error.message.toLowerCase();
31
+ if (msg.includes("not supported")) return XR_ERROR_MESSAGES["NotSupportedError"];
32
+ if (msg.includes("permission") || msg.includes("denied")) return XR_ERROR_MESSAGES["SecurityError"];
33
+ }
34
+ return XR_ERROR_MESSAGE_UNKNOWN;
35
+ }
36
+ //#endregion
37
+ export { XR_ERROR_MESSAGES, XR_ERROR_MESSAGE_UNKNOWN, getXrErrorMessage };
@@ -0,0 +1,82 @@
1
+ import { Quaternion, Vector3 } from "gps-plus-slam-js";
2
+
3
+ //#region ../src/types/ar-types.d.ts
4
+ /**
5
+ * Tuple-form AR pose for storage/serialization.
6
+ *
7
+ * The tuple equivalent of ARPose — uses the library's readonly Vector3/Quaternion
8
+ * tuples instead of object-form { x, y, z }. Used in storage interfaces where
9
+ * poses are persisted as plain number arrays in JSON.
10
+ *
11
+ * @see ARPose for the object-form variant used in live AR tracking
12
+ * @see 2026-03-03-code-review-inline-type-duplication.md Finding #6
13
+ */
14
+ interface ArPoseTuples {
15
+ readonly position: Vector3;
16
+ readonly rotation: Quaternion;
17
+ }
18
+ /**
19
+ * 3D position in object-form as returned by the WebXR API (XRViewerPose).
20
+ * Distinct from the library's tuple-form `Vector3` (`readonly [number, number, number]`).
21
+ */
22
+ interface WebXRVec3 {
23
+ readonly x: number;
24
+ readonly y: number;
25
+ readonly z: number;
26
+ }
27
+ /**
28
+ * Quaternion orientation in object-form as returned by the WebXR API (XRViewerPose).
29
+ * Distinct from the library's tuple-form `Quaternion` (`readonly [number, number, number, number]`).
30
+ */
31
+ interface WebXRQuaternion {
32
+ readonly x: number;
33
+ readonly y: number;
34
+ readonly z: number;
35
+ readonly w: number;
36
+ }
37
+ /**
38
+ * Device pose in AR space.
39
+ * Position and orientation are in the local-floor reference space.
40
+ * This is the RAW pose, NOT transformed by any alignment matrix.
41
+ */
42
+ interface ARPose {
43
+ readonly position: WebXRVec3;
44
+ readonly orientation: WebXRQuaternion;
45
+ }
46
+ /**
47
+ * A single depth point sample from WebXR Depth API.
48
+ * Used for 3D reconstruction and validating AR tracking accuracy.
49
+ */
50
+ interface DepthPoint {
51
+ /** Normalized screen X coordinate (0-1) */
52
+ readonly screenX: number;
53
+ /** Normalized screen Y coordinate (0-1) */
54
+ readonly screenY: number;
55
+ /** Depth value in meters */
56
+ readonly depthM: number;
57
+ }
58
+ /**
59
+ * A complete depth sample with camera pose and grid of depth points.
60
+ * Produced by the depth sampler at ~1 Hz, consumed by the store for
61
+ * persistence and replay. This is the single canonical type, re-exported
62
+ * by `store.ts` for dispatch convenience.
63
+ */
64
+ interface DepthSample {
65
+ /** Timestamp in milliseconds */
66
+ readonly timestamp: number;
67
+ /**
68
+ * Camera position in **raw WebXR** convention [x=East, y=Up, z=South].
69
+ * NOT in NUE — the recordDepthSample reducer is a no-op, so no
70
+ * webxrToNUE conversion is applied. Consumers must convert if needed.
71
+ */
72
+ readonly cameraPos: Vector3;
73
+ /**
74
+ * Camera rotation quaternion in **raw WebXR** convention [x, y, z, w].
75
+ * NOT in NUE — same reasoning as cameraPos.
76
+ */
77
+ readonly cameraRot: Quaternion;
78
+ /** Grid of depth points */
79
+ readonly points: DepthPoint[];
80
+ }
81
+ //#endregion
82
+ export { WebXRQuaternion as a, DepthSample as i, ArPoseTuples as n, WebXRVec3 as o, DepthPoint as r, ARPose as t };
@@ -0,0 +1,108 @@
1
+ import * as THREE from "three";
2
+
3
+ //#region ../src/ar/camera-blit-capture.d.ts
4
+ /**
5
+ * Configuration for the blit capture render target dimensions.
6
+ * Smaller = faster readPixels (less GPU stall), but lower resolution.
7
+ */
8
+ interface CameraBlitCaptureConfig {
9
+ /** Width of the intermediate render target in pixels */
10
+ width: number;
11
+ /** Height of the intermediate render target in pixels */
12
+ height: number;
13
+ }
14
+ /**
15
+ * Default blit capture config.
16
+ * 512×512 is a good balance between quality and readPixels performance on mobile.
17
+ */
18
+ declare const DEFAULT_BLIT_CONFIG: CameraBlitCaptureConfig;
19
+ /**
20
+ * Compute the capture dimensions from the native camera resolution
21
+ * and a user-configurable resolution divisor.
22
+ *
23
+ * @param cameraWidth - Native camera width in pixels (from XRCamera)
24
+ * @param cameraHeight - Native camera height in pixels (from XRCamera)
25
+ * @param divisor - Resolution divisor: 1 = full, 2 = half, 4 = quarter, etc.
26
+ * Values ≤ 0 are treated as 1. Fractional values < 1 are treated as 1.
27
+ * @returns Integer pixel dimensions, clamped to at least 1×1.
28
+ * Falls back to DEFAULT_BLIT_CONFIG when inputs are invalid (≤ 0).
29
+ */
30
+ declare function computeCaptureSize(cameraWidth: number, cameraHeight: number, divisor: number): {
31
+ width: number;
32
+ height: number;
33
+ };
34
+ /**
35
+ * Captures readable pixel data from WebXR opaque camera textures
36
+ * using the intermediate render target "blit" technique.
37
+ *
38
+ * Usage:
39
+ * 1. Create once when AR session starts
40
+ * 2. Call captureToBlob() when a frame needs to be captured
41
+ * 3. Call dispose() when AR session ends
42
+ */
43
+ declare class CameraBlitCapture {
44
+ private renderTarget;
45
+ private blitScene;
46
+ private blitCamera;
47
+ private blitMaterial;
48
+ private quad;
49
+ private pixelBuffer;
50
+ private width;
51
+ private height;
52
+ private disposed;
53
+ constructor(config?: CameraBlitCaptureConfig);
54
+ /**
55
+ * Capture the WebXR camera texture to a JPEG Blob via the blit technique.
56
+ *
57
+ * IMPORTANT: Must be called within the XR animation frame callback,
58
+ * while the camera texture is valid.
59
+ *
60
+ * @param renderer - The Three.js WebGL renderer
61
+ * @param cameraTexture - The opaque camera texture from renderer.xr.getCameraTexture()
62
+ * @param quality - JPEG quality 0.0-1.0
63
+ * @returns JPEG Blob, or null if capture fails
64
+ */
65
+ captureToBlob(renderer: THREE.WebGLRenderer, cameraTexture: THREE.Texture, quality: number): Promise<Blob | null>;
66
+ /**
67
+ * Check if a pixel buffer is entirely black (all zeros).
68
+ * Uses sampling for performance (checks BLACK_CHECK_SAMPLE_COUNT evenly-spaced pixels).
69
+ *
70
+ * This is useful to detect if the blit technique failed to convert
71
+ * the opaque texture (different from a legitimately dark scene).
72
+ *
73
+ * @param pixels - RGBA pixel buffer
74
+ * @returns true if all sampled pixels are zero
75
+ */
76
+ static isBlackFrame(pixels: Uint8Array): boolean;
77
+ /**
78
+ * Convert the internal pixel buffer to a JPEG Blob using OffscreenCanvas
79
+ * (or fallback to regular Canvas).
80
+ */
81
+ private pixelsToJpegBlob;
82
+ private getFlippedImageData;
83
+ private pixelsToJpegViaOffscreenCanvas;
84
+ private pixelsToJpegViaCanvas;
85
+ /**
86
+ * Flip ImageData vertically in-place.
87
+ * WebGL readPixels returns bottom-row-first; canvas expects top-row-first.
88
+ */
89
+ private flipImageDataVertically;
90
+ /**
91
+ * Resize the render target and pixel buffer to match new dimensions.
92
+ * Call this when the camera resolution is first known or changes.
93
+ *
94
+ * No-op when dimensions already match (avoids per-frame reallocation).
95
+ * Returns false if disposed, dimensions unchanged, or dimensions invalid.
96
+ *
97
+ * @param newWidth - Desired capture width in pixels
98
+ * @param newHeight - Desired capture height in pixels
99
+ * @returns true if resources were actually resized
100
+ */
101
+ resizeIfNeeded(newWidth: number, newHeight: number): boolean;
102
+ /**
103
+ * Dispose GPU resources. Call when AR session ends.
104
+ */
105
+ dispose(): void;
106
+ }
107
+ //#endregion
108
+ export { computeCaptureSize as i, CameraBlitCaptureConfig as n, DEFAULT_BLIT_CONFIG as r, CameraBlitCapture as t };
@@ -0,0 +1,29 @@
1
+ import * as THREE from "three";
2
+
3
+ //#region ../src/visualization/camera-follower.d.ts
4
+ interface CameraFollower {
5
+ /** The underlying Object3D — add children (map, cubes) here. */
6
+ readonly object3D: THREE.Object3D;
7
+ /**
8
+ * Update the follower position. Call once per frame before render.
9
+ *
10
+ * @param camera The active camera (its world position is read).
11
+ * @param dt Delta time in seconds since last frame.
12
+ */
13
+ update(camera: THREE.Camera, dt: number): void;
14
+ /** Remove the follower from the scene graph. */
15
+ dispose(): void;
16
+ }
17
+ /**
18
+ * Create a CameraFollower and attach it as a child of the given parent.
19
+ *
20
+ * The parent should be the scene root (not arWorldGroup) so that the
21
+ * follower's world rotation stays identity — ensuring compass directions
22
+ * align with the NUE GPS frame regardless of alignment matrix changes.
23
+ *
24
+ * @param parent Parent node — should be the scene root.
25
+ * @param lerpRate Lerp speed multiplier (default 8).
26
+ */
27
+ declare function createCameraFollower(parent: THREE.Object3D, lerpRate?: number): CameraFollower;
28
+ //#endregion
29
+ export { createCameraFollower as n, CameraFollower as t };
@@ -0,0 +1,52 @@
1
+ //#region ../src/ar/capture-failure-tracker.d.ts
2
+ /**
3
+ * Capture Failure Tracker
4
+ *
5
+ * Tracks consecutive image capture failures and notifies users when
6
+ * multiple frames fail to capture (e.g., low memory on mobile devices).
7
+ *
8
+ * Field Test Readiness Issue #11: Silent image capture failures
9
+ *
10
+ * Thin wrapper around the generic failure tracker factory.
11
+ */
12
+ /**
13
+ * Configuration for the capture failure tracker.
14
+ */
15
+ interface CaptureFailureTrackerConfig {
16
+ /**
17
+ * Number of consecutive failures before warning the user.
18
+ * Default: 5 (higher than write failures since capture failures are less critical)
19
+ */
20
+ failureThreshold: number;
21
+ /**
22
+ * Callback to show error to user.
23
+ */
24
+ onWarning: (message: string) => void;
25
+ }
26
+ /**
27
+ * Default configuration values.
28
+ */
29
+ declare const DEFAULT_CAPTURE_TRACKER_CONFIG: Omit<CaptureFailureTrackerConfig, 'onWarning'>;
30
+ /**
31
+ * User-facing warning message when threshold is exceeded.
32
+ */
33
+ declare const CAPTURE_FAILURE_WARNING = "Multiple image captures failed. Device may be low on memory.";
34
+ /**
35
+ * Tracks consecutive capture failures and warns user when threshold is exceeded.
36
+ */
37
+ interface CaptureFailureTracker {
38
+ recordSuccess(): void;
39
+ recordFailure(): void;
40
+ getFailureCount(): number;
41
+ hasWarned(): boolean;
42
+ reset(): void;
43
+ }
44
+ /**
45
+ * Create a new capture failure tracker.
46
+ *
47
+ * @param config - Configuration with warning callback and optional threshold
48
+ * @returns CaptureFailureTracker instance
49
+ */
50
+ declare function createCaptureFailureTracker(config: Partial<CaptureFailureTrackerConfig> & Pick<CaptureFailureTrackerConfig, 'onWarning'>): CaptureFailureTracker;
51
+ //#endregion
52
+ export { createCaptureFailureTracker as a, DEFAULT_CAPTURE_TRACKER_CONFIG as i, CaptureFailureTracker as n, CaptureFailureTrackerConfig as r, CAPTURE_FAILURE_WARNING as t };
@@ -0,0 +1,61 @@
1
+ //#region ../src/ar/chromium-camera-access-workaround.d.ts
2
+ /**
3
+ * Chromium WebXR camera-access tab-crash workaround.
4
+ *
5
+ * Background:
6
+ * Requesting `camera-access` as an optional WebXR feature on recent Android
7
+ * Chrome versions causes a fatal renderer-process crash (`CrRendererMain`)
8
+ * 1–2 seconds after entering AR. The crash reproduces in the upstream
9
+ * three.js `webxr_ar_hittest.html` example with `optionalFeatures:
10
+ * ['camera-access']` added — i.e. it is not specific to this app's session
11
+ * setup. See:
12
+ *
13
+ * - GpsPlusSlamJs_Docs/docs/2026-04-22-camera-access-reproducer-plan.md
14
+ * - GpsPlusSlamJs_Docs/docs/2026-04-23-webxr-camera-access-crash-bug-report.html
15
+ * - https://github.com/mrdoob/three.js/issues/33404
16
+ *
17
+ * Workaround (from the upstream issue thread):
18
+ * Three.js's `WebXRManager` chooses between the newer `XRProjectionLayer`
19
+ * and the older `XRWebGLLayer` based on whether
20
+ * `XRWebGLBinding.prototype.createProjectionLayer` is available. The crash
21
+ * appears to involve the projection-layer + camera-access combination, so
22
+ * removing the prototype method forces three.js to fall back to
23
+ * `XRWebGLLayer`, which sidesteps the bug.
24
+ *
25
+ * `XRRenderState.prototype.layers` is the equivalent capability check used
26
+ * by older three.js (r158-era) and is included for completeness.
27
+ *
28
+ * Caveats:
29
+ * - This is a Chromium-specific hack and the upstream comment explicitly
30
+ * warns it "might break webxr on other devices" — keep it opt-in.
31
+ * - Must run BEFORE any WebXR session setup. Three.js reads these prototype
32
+ * members lazily when the first session starts, so calling this at app
33
+ * bootstrap (before `initAR()`) is sufficient.
34
+ * - Idempotent: safe to call repeatedly. Safe on environments where the
35
+ * prototypes do not exist (e.g. desktop browsers, jsdom).
36
+ */
37
+ /**
38
+ * Result of {@link applyChromiumProjectionLayerWorkaround}.
39
+ * Useful for logging and tests.
40
+ */
41
+ interface ChromiumProjectionLayerWorkaroundResult {
42
+ /** True if `XRWebGLBinding.prototype.createProjectionLayer` was deleted on this call. */
43
+ deletedCreateProjectionLayer: boolean;
44
+ /** True if `XRRenderState.prototype.layers` was deleted on this call. */
45
+ deletedRenderStateLayers: boolean;
46
+ }
47
+ /**
48
+ * Apply the Chromium camera-access tab-crash workaround.
49
+ *
50
+ * Removes `XRWebGLBinding.prototype.createProjectionLayer` (three.js r184)
51
+ * and `XRRenderState.prototype.layers` (three.js r158) so three.js falls
52
+ * back to `XRWebGLLayer`, which avoids the renderer-process crash that
53
+ * happens when both projection layers and `camera-access` are enabled.
54
+ *
55
+ * Call once during bootstrap, before any `requestSession()` call.
56
+ *
57
+ * @returns which prototype members were actually deleted on this call.
58
+ */
59
+ declare function applyChromiumProjectionLayerWorkaround(): ChromiumProjectionLayerWorkaroundResult;
60
+ //#endregion
61
+ export { applyChromiumProjectionLayerWorkaround as n, ChromiumProjectionLayerWorkaroundResult as t };
@@ -0,0 +1,21 @@
1
+ //#region ../src/licensing/community-license-key.d.ts
2
+ /**
3
+ * Community license key for the gps-plus-slam-js core library.
4
+ *
5
+ * Generated by the core library maintainers and bundled with the open-source
6
+ * `gps-plus-slam-app-framework` package so that every example app (and any
7
+ * downstream app built on the framework) automatically uses a valid license
8
+ * without per-developer registration.
9
+ *
10
+ * The key has a rolling expiration of 12 months. Each release of the
11
+ * open-source packages renews it. Active users who regularly update their
12
+ * dependencies will never be affected by the expiration.
13
+ *
14
+ * For licenses with extended validity beyond the community key's scope,
15
+ * contact support@csutil.com.
16
+ *
17
+ * @see GpsPlusSlamJs/EULA.md §3 — License Key
18
+ */
19
+ declare const COMMUNITY_LICENSE_KEY = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODA4NzcyNDI3fQ.YYNf0IdqniZdMzRXCuvewxsQQ01XNywrKsfL5IpiJotfFJfqtrGg4u9z0QFhXeszPtUhnvgC8_oOnbOkbXPuAw";
20
+ //#endregion
21
+ export { COMMUNITY_LICENSE_KEY as t };
@@ -0,0 +1,24 @@
1
+ //#region ../src/utils/concurrency.d.ts
2
+ /**
3
+ * Concurrency Utilities
4
+ *
5
+ * Provides helpers for limiting the number of concurrent async operations.
6
+ * Used to prevent excessive memory consumption when scanning many files
7
+ * in parallel (e.g., reading zip metadata during scenario discovery).
8
+ */
9
+ /**
10
+ * Map over an array with a concurrency limit on the async mapper function.
11
+ *
12
+ * Behaves like `Promise.all(items.map(fn))` but limits how many mapper
13
+ * invocations run simultaneously. Results are returned in the same order
14
+ * as the input items.
15
+ *
16
+ * @param items - Array of items to process
17
+ * @param limit - Maximum number of concurrent mapper invocations
18
+ * @param mapper - Async function to apply to each item
19
+ * @returns Array of results in the same order as input items
20
+ * @throws Re-throws the first error from any mapper invocation (fail-fast)
21
+ */
22
+ declare function mapWithConcurrencyLimit<T, R>(items: T[], limit: number, mapper: (item: T, index: number) => Promise<R>): Promise<R[]>;
23
+ //#endregion
24
+ export { mapWithConcurrencyLimit as t };
@@ -0,0 +1,23 @@
1
+ import * as THREE from "three";
2
+
3
+ //#region ../src/visualization/css3d-renderer-manager.d.ts
4
+ interface Css3dRendererManager {
5
+ render(scene: THREE.Scene, camera: THREE.Camera): void;
6
+ setSize(width: number, height: number): void;
7
+ dispose(): void;
8
+ }
9
+ /**
10
+ * Create and configure a CSS3DRenderer overlay for the given container.
11
+ *
12
+ * The CSS3D layer is positioned absolutely over the container with
13
+ * `pointer-events: none` so it does not intercept clicks intended
14
+ * for the WebGL canvas underneath.
15
+ *
16
+ * **Requirement:** The `container` element must have `position: relative`,
17
+ * `absolute`, `fixed`, or `sticky`. If the container is `position: static`
18
+ * (the CSS default), the overlay will float to the nearest positioned
19
+ * ancestor instead of aligning with the container.
20
+ */
21
+ declare function createCss3dRendererManager(container: HTMLElement, width: number, height: number): Css3dRendererManager;
22
+ //#endregion
23
+ export { createCss3dRendererManager as n, Css3dRendererManager as t };
@@ -0,0 +1,108 @@
1
+ import { i as DepthSample, t as ARPose } from "./ar-types-B-ORgk6Z.js";
2
+
3
+ //#region ../src/ar/depth-sampler.d.ts
4
+ /**
5
+ * Configuration for depth sampling behavior.
6
+ */
7
+ interface DepthSamplerConfig {
8
+ /** Interval between samples in milliseconds. Default: 1000ms */
9
+ intervalMs: number;
10
+ /** Number of points per dimension (gridSize x gridSize). Default: 3 */
11
+ gridSize: number;
12
+ /** Time in ms to wait before declaring depth unavailable. Default: 5000ms */
13
+ unavailabilityThresholdMs: number;
14
+ }
15
+ /**
16
+ * Callbacks for depth sampler events.
17
+ */
18
+ interface DepthSamplerCallbacks {
19
+ /** Called when a depth sample is captured */
20
+ onSampleCaptured: (sample: DepthSample) => void;
21
+ /** Returns the current AR pose, or null if not available */
22
+ getCurrentPose: () => ARPose | null;
23
+ /**
24
+ * Called once when depth is determined to be unavailable.
25
+ * Triggered after unavailabilityThresholdMs with no depth data.
26
+ * Field Test Readiness Issue #8.
27
+ */
28
+ onDepthUnavailable?: () => void;
29
+ }
30
+ /**
31
+ * WebXR depth info interface (subset of XRDepthInformation).
32
+ */
33
+ interface DepthInfo {
34
+ width: number;
35
+ height: number;
36
+ getDepthInMeters: (x: number, y: number) => number;
37
+ }
38
+ /**
39
+ * Samples sparse depth points from WebXR depth sensing.
40
+ *
41
+ * Usage:
42
+ * ```ts
43
+ * const sampler = new DepthSampler({
44
+ * onSampleCaptured: (sample) => saveSample(sample),
45
+ * getCurrentPose: () => arSession.getCurrentPose(),
46
+ * });
47
+ * sampler.start();
48
+ * // In frame loop:
49
+ * sampler.onFrame(timestamp, depthInfo);
50
+ * ```
51
+ */
52
+ declare class DepthSampler {
53
+ private readonly callbacks;
54
+ private readonly config;
55
+ private running;
56
+ private sampleCount;
57
+ private lastSampleTime;
58
+ /** Timestamp when sampling started (for unavailability detection) */
59
+ private startTime;
60
+ /** Whether we've ever received valid depth data */
61
+ private depthReceived;
62
+ /** Whether we've already fired the unavailable callback */
63
+ private unavailableCallbackFired;
64
+ constructor(callbacks: DepthSamplerCallbacks, config?: Partial<DepthSamplerConfig>);
65
+ /**
66
+ * Start depth sampling.
67
+ */
68
+ start(): void;
69
+ /**
70
+ * Stop depth sampling.
71
+ */
72
+ stop(): void;
73
+ /**
74
+ * Check if sampler is currently running.
75
+ */
76
+ isRunning(): boolean;
77
+ /**
78
+ * Get the number of samples captured since start.
79
+ */
80
+ getSampleCount(): number;
81
+ /**
82
+ * Get the current configuration.
83
+ */
84
+ getConfig(): DepthSamplerConfig;
85
+ /**
86
+ * Called each frame with depth information.
87
+ *
88
+ * @param timestamp - Current frame timestamp in milliseconds
89
+ * @param depthInfo - WebXR depth information, or null if unavailable
90
+ */
91
+ onFrame(timestamp: number, depthInfo: DepthInfo | null): void;
92
+ /**
93
+ * Sample a grid of depth points from the depth buffer.
94
+ */
95
+ private sampleGrid;
96
+ /**
97
+ * Check if depth has been unavailable for longer than the threshold.
98
+ * If so, fire the onDepthUnavailable callback (once).
99
+ */
100
+ private checkDepthUnavailability;
101
+ /**
102
+ * Check if depth data has ever been received.
103
+ * Useful for testing and status display.
104
+ */
105
+ hasReceivedDepth(): boolean;
106
+ }
107
+ //#endregion
108
+ export { DepthSamplerConfig as i, DepthSampler as n, DepthSamplerCallbacks as r, DepthInfo as t };
@@ -0,0 +1,49 @@
1
+ //#region ../src/utils/failure-tracker.d.ts
2
+ /**
3
+ * Generic Failure Tracker Factory
4
+ *
5
+ * Shared pattern extracted from capture-failure-tracker and write-failure-tracker.
6
+ * Tracks consecutive failures, warns the user once when a threshold is exceeded,
7
+ * and supports session-level reset.
8
+ */
9
+ /**
10
+ * Configuration for creating a failure tracker.
11
+ */
12
+ interface FailureTrackerConfig {
13
+ /** Human-readable label used for log messages (e.g., 'CaptureFailure'). */
14
+ label: string;
15
+ /** Message passed to `onWarning` when the threshold is reached. */
16
+ warningMessage: string;
17
+ /** Default threshold used when `failureThreshold` is not provided. */
18
+ defaultThreshold: number;
19
+ /** Callback invoked once when consecutive failures reach the threshold. */
20
+ onWarning: (message: string) => void;
21
+ /** Optional override for the failure threshold. */
22
+ failureThreshold?: number;
23
+ /** Log level for each failure: 'warn' (default) or 'error'. */
24
+ logLevel?: 'warn' | 'error';
25
+ }
26
+ /**
27
+ * A failure tracker instance returned by `createFailureTracker`.
28
+ */
29
+ interface FailureTracker {
30
+ /** Record a success — resets the consecutive failure counter. */
31
+ recordSuccess(): void;
32
+ /** Record a failure (optionally with an error for logging). */
33
+ recordFailure(error?: unknown): void;
34
+ /** Current number of consecutive failures. */
35
+ getFailureCount(): number;
36
+ /** Whether the warning has already been shown this session. */
37
+ hasWarned(): boolean;
38
+ /** Reset all state (for new sessions). */
39
+ reset(): void;
40
+ }
41
+ /**
42
+ * Create a generic failure tracker.
43
+ *
44
+ * @param config - Tracker configuration
45
+ * @returns A FailureTracker instance
46
+ */
47
+ declare function createFailureTracker(config: FailureTrackerConfig): FailureTracker;
48
+ //#endregion
49
+ export { FailureTrackerConfig as n, createFailureTracker as r, FailureTracker as t };