gps-plus-slam-app-framework 1.10.0 → 1.13.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 (289) hide show
  1. package/README.md +27 -28
  2. package/dist/{absolute-orientation-C_IxDR_j.d.ts → absolute-orientation-0WIsqJnu.d.ts} +1 -1
  3. package/dist/{accuracy-circles-BE7tbvYV.d.ts → accuracy-circles-CFnKGfsD.d.ts} +1 -1
  4. package/dist/{app-selectors-CV7ggGoo.d.ts → app-selectors-QM0ZpNA4.d.ts} +1 -1
  5. package/dist/ar/ar-crash-isolation.d.ts +2 -0
  6. package/dist/ar/ar-crash-isolation.js +40 -0
  7. package/dist/ar/bresenham3d.d.ts +1 -1
  8. package/dist/ar/camera-blit-capture.d.ts +1 -1
  9. package/dist/ar/capability-checker.d.ts +1 -1
  10. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  11. package/dist/ar/capture-motion-gate.d.ts +2 -0
  12. package/dist/{capture-motion-gate-D1eyGC_o.js → ar/capture-motion-gate.js} +25 -2
  13. package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
  14. package/dist/ar/chromium-camera-access-workaround.js +1 -1
  15. package/dist/ar/depth-grid-lookup.d.ts +1 -1
  16. package/dist/ar/depth-occluder.d.ts +1 -1
  17. package/dist/ar/depth-occluder.js +1 -1
  18. package/dist/ar/depth-sampler.d.ts +3 -3
  19. package/dist/ar/depth-sampler.js +28 -1
  20. package/dist/ar/depth-unprojection.d.ts +1 -1
  21. package/dist/ar/enable-gps-ar.d.ts +1 -1
  22. package/dist/ar/enable-gps-ar.js +20 -5
  23. package/dist/ar/frame-loop.d.ts +1 -1
  24. package/dist/ar/hit-test-reticle-driver.d.ts +2 -0
  25. package/dist/ar/hit-test-reticle-driver.js +122 -0
  26. package/dist/ar/image-capture.d.ts +1 -1
  27. package/dist/ar/image-capture.js +1 -1
  28. package/dist/ar/image-quality.d.ts +2 -2
  29. package/dist/ar/image-quality.js +136 -4
  30. package/dist/ar/index.d.ts +35 -32
  31. package/dist/ar/index.js +17 -15
  32. package/dist/ar/occlusion-mesh-worker.d.ts +2 -2
  33. package/dist/ar/occlusion-mesh-worker.js +6 -4
  34. package/dist/ar/occupancy-grid.d.ts +2 -2
  35. package/dist/ar/occupancy-grid.js +192 -12
  36. package/dist/ar/occupancy-mesher.d.ts +1 -1
  37. package/dist/ar/occupancy-mesher.js +1 -636
  38. package/dist/ar/qr/index.d.ts +11 -0
  39. package/dist/ar/qr/index.js +11 -0
  40. package/dist/ar/{planar-pnp.d.ts → qr/planar-pnp.d.ts} +1 -1
  41. package/dist/ar/{planar-pnp.js → qr/planar-pnp.js} +1 -1
  42. package/dist/ar/qr/qr-debug-view.d.ts +2 -0
  43. package/dist/ar/{qr-debug-view.js → qr/qr-debug-view.js} +2 -2
  44. package/dist/ar/{qr-derived-pose.d.ts → qr/qr-derived-pose.d.ts} +1 -1
  45. package/dist/ar/{qr-derived-pose.js → qr/qr-derived-pose.js} +2 -2
  46. package/dist/ar/{qr-detection-controller.d.ts → qr/qr-detection-controller.d.ts} +1 -1
  47. package/dist/ar/qr/qr-detection-controller.js +2 -0
  48. package/dist/ar/{qr-frontend.d.ts → qr/qr-frontend.d.ts} +1 -1
  49. package/dist/ar/{qr-frontend.js → qr/qr-frontend.js} +1 -1
  50. package/dist/ar/{qr-pose.d.ts → qr/qr-pose.d.ts} +1 -1
  51. package/dist/ar/{qr-pose.js → qr/qr-pose.js} +1 -1
  52. package/dist/ar/qr/qr-size-depth-context.d.ts +3 -0
  53. package/dist/ar/{qr-size-depth-context.js → qr/qr-size-depth-context.js} +4 -4
  54. package/dist/ar/{qr-size-measurer.d.ts → qr/qr-size-measurer.d.ts} +1 -1
  55. package/dist/ar/qr/qr-size-measurer.js +2 -0
  56. package/dist/ar/replay-scene.d.ts +1 -1
  57. package/dist/ar/replay-scene.js +15 -13
  58. package/dist/ar/scene-node-names.d.ts +1 -1
  59. package/dist/ar/webxr-nue-basis.d.ts +1 -1
  60. package/dist/ar/webxr-session.d.ts +4 -4
  61. package/dist/ar/webxr-session.js +2 -2
  62. package/dist/ar/xr-camera-texture.d.ts +1 -1
  63. package/dist/ar/xr-error-handler.d.ts +1 -1
  64. package/dist/ar/xr-frame-loop.d.ts +1 -1
  65. package/dist/ar/xr-frame-loop.js +1 -1
  66. package/dist/ar-crash-isolation-BSFw_beO.d.ts +52 -0
  67. package/dist/{ar-world-group-alignment-B6XiA1cT.d.ts → ar-world-group-alignment-CvvfACfx.d.ts} +2 -2
  68. package/dist/{capability-checker-DEo-ktWI.d.ts → capability-checker-DrWimJ_t.d.ts} +1 -1
  69. package/dist/capture-motion-gate-C60Qrilh.d.ts +120 -0
  70. package/dist/{cell-key-Bj-eYTLA.js → cell-key-D1b_Ix-p.js} +12 -1
  71. package/dist/{chromium-camera-access-workaround-DCd8SP2N.d.ts → chromium-camera-access-workaround-BRs6gkI4.d.ts} +1 -1
  72. package/dist/core/index.d.ts +1 -1
  73. package/dist/{create-slam-app-store-CH31erpP.d.ts → create-slam-app-store-HNe1PBtx.d.ts} +37 -6
  74. package/dist/{create-slam-app-store-DLv5ZwqU.js → create-slam-app-store-wYN7YkB5.js} +21 -10
  75. package/dist/{depth-grid-lookup-DY6zYTLx.d.ts → depth-grid-lookup-PcJTdRLL.d.ts} +1 -1
  76. package/dist/{depth-sampler-txG8evgQ.d.ts → depth-sampler-BcvuxgCS.d.ts} +30 -3
  77. package/dist/{depth-unprojection-JKkeqJrV.d.ts → depth-unprojection-DbGipFkA.d.ts} +1 -1
  78. package/dist/{enable-gps-ar-BbNWyqp5.d.ts → enable-gps-ar-xjz3jNqm.d.ts} +10 -5
  79. package/dist/{file-system-utils-CfLTj5Ra.d.ts → file-system-utils-DE3BViuq.d.ts} +1 -1
  80. package/dist/{frame-conversions-CH7E2Iv_.d.ts → frame-conversions-CzPQDYpM.d.ts} +1 -1
  81. package/dist/{fused-path-DOKzVMiO.d.ts → fused-path-CBAttcVm.d.ts} +1 -1
  82. package/dist/geo/h3-proximity.d.ts +1 -1
  83. package/dist/geo/h3-proximity.js +1 -1
  84. package/dist/geo/index.d.ts +1 -1
  85. package/dist/{geodesic-angle-HXBWiXiI.js → geodesic-angle-CZ_Ow90I.js} +2 -2
  86. package/dist/{gps-anchor-BaqyRsPC.d.ts → gps-anchor-Gv4NDwH4.d.ts} +1 -1
  87. package/dist/{gps-ar-pose-sampler-BOOV0jJk.d.ts → gps-ar-pose-sampler-DBEYDFY5.d.ts} +1 -1
  88. package/dist/{gps-event-coordinator-03rVh_us.d.ts → gps-event-coordinator-BKwB4RyQ.d.ts} +4 -4
  89. package/dist/{gps-event-markers-BsC2Ynlh.d.ts → gps-event-markers-212h7j3D.d.ts} +39 -5
  90. package/dist/{h3-proximity-pFluGfwL.d.ts → h3-proximity-CAEk3osq.d.ts} +1 -1
  91. package/dist/hit-test-reticle-driver-CfKiDgsa.d.ts +40 -0
  92. package/dist/{image-capture-Cr_rljeV.d.ts → image-capture-BXmx1YvD.d.ts} +6 -6
  93. package/dist/{image-capture-BUqqsOi3.js → image-capture-Dn8uLIP2.js} +3 -3
  94. package/dist/{image-quality-BjBLoTec.d.ts → image-quality-G7_qT4aj.d.ts} +44 -2
  95. package/dist/index-DVmgFIgm.d.ts +64 -0
  96. package/dist/{index-C2Bo0buN.d.ts → index-DX9VC257.d.ts} +10 -72
  97. package/dist/{index-CuHaGY0F.d.ts → index-qtZ2muFd.d.ts} +1 -1
  98. package/dist/index.d.ts +89 -82
  99. package/dist/index.js +31 -24
  100. package/dist/{leaflet-map-overlay-QhF199BW.d.ts → leaflet-map-overlay-BkHmzvpD.d.ts} +1 -1
  101. package/dist/{leaflet-map-overlay-BRkUhZMD.js → leaflet-map-overlay-DjWfRT8a.js} +1 -1
  102. package/dist/{map-data-D8sSxpOr.d.ts → map-data-BQXPtRz7.d.ts} +3 -3
  103. package/dist/{map-data-D3oE8AQP.js → map-data-vL8jb5Z9.js} +1 -1
  104. package/dist/{map-overlay-draw-1E61FLKs.d.ts → map-overlay-draw-sTM3wug_.d.ts} +1 -1
  105. package/dist/{median-Bla_W50f.js → median-DDBrZGP0.js} +2 -2
  106. package/dist/{null-storage-backend-DXXuwG8T.d.ts → null-storage-backend-Dtn3TBfT.d.ts} +2 -2
  107. package/dist/{occlusion-mesh-CZ4i_SW2.d.ts → occlusion-mesh-BY2aMej3.d.ts} +43 -6
  108. package/dist/occupancy-cubes-visualizer-soN0Sizd.d.ts +146 -0
  109. package/dist/{occupancy-grid-f0I07UxI.d.ts → occupancy-grid-DKzIdCSZ.d.ts} +114 -4
  110. package/dist/{occupancy-mesher-BqnRd10x.d.ts → occupancy-mesher-Co80tOpl.d.ts} +22 -1
  111. package/dist/occupancy-mesher-DzNeJdQf.js +837 -0
  112. package/dist/{opfs-storage-backend-D1ZpeNEL.d.ts → opfs-storage-backend-CZ-ECudx.d.ts} +2 -2
  113. package/dist/perf-stats-overlay-BMEQrzx6.d.ts +68 -0
  114. package/dist/{persistence-middleware-CI4Cetnl.d.ts → persistence-middleware-Byo_Fs4n.d.ts} +13 -3
  115. package/dist/{planar-pnp-CPLhg5MX.d.ts → planar-pnp-CkcMN3o3.d.ts} +2 -2
  116. package/dist/pointer-picking-BATHHTlT.d.ts +41 -0
  117. package/dist/{ar-D-03Kso-.js → qr-CTp5xI83.js} +11 -25
  118. package/dist/{qr-debug-view-BmbWo06j.d.ts → qr-debug-view-BMjNVhV2.d.ts} +2 -2
  119. package/dist/{qr-derived-pose-DEYT85ul.d.ts → qr-derived-pose-Dq7mPK2s.d.ts} +3 -3
  120. package/dist/{qr-detected-slice-CPEkGbxh.d.ts → qr-detected-slice-8t_laDR9.d.ts} +9 -8
  121. package/dist/{qr-detection-controller-bRTJXC6G.js → qr-detection-controller-DXc1yHRf.js} +3 -3
  122. package/dist/{qr-detection-controller-IcMRpTjV.d.ts → qr-detection-controller-Dh4Paymb.d.ts} +4 -4
  123. package/dist/{qr-frontend-61SKPSyU.d.ts → qr-frontend-BnLlVjKu.d.ts} +2 -2
  124. package/dist/{qr-pose-CCTF1PP0.d.ts → qr-pose-_dInl6di.d.ts} +1 -1
  125. package/dist/{qr-pose-aggregation-BL6gfl0s.d.ts → qr-pose-aggregation-Bpv4uARJ.d.ts} +2 -2
  126. package/dist/{qr-pose-aggregation-H-O_Jjz9.js → qr-pose-aggregation-Cp0Mtg_j.js} +4 -4
  127. package/dist/{qr-size-depth-context-DJsYqbqY.d.ts → qr-size-depth-context-Bzbx98nS.d.ts} +3 -3
  128. package/dist/{qr-size-measurer-Bl_i-umk.d.ts → qr-size-measurer-18_W3INY.d.ts} +5 -5
  129. package/dist/{qr-size-measurer-BVOIg-He.js → qr-size-measurer-zZB9S1va.js} +4 -4
  130. package/dist/{recording-replayer-DyIN13nG.d.ts → recording-replayer-BKmVuchg.d.ts} +2 -2
  131. package/dist/{recording-slice-DziOl7P5.d.ts → recording-slice-zMedT0ot.d.ts} +10 -5
  132. package/dist/{replay-engine-DAymjsd1.d.ts → replay-engine-D-cbT0Fw.d.ts} +1 -1
  133. package/dist/{replay-scene-CZdWgcpc.d.ts → replay-scene-D5qzY0_x.d.ts} +12 -5
  134. package/dist/sensors/absolute-orientation.d.ts +1 -1
  135. package/dist/sensors/absolute-orientation.js +1 -1
  136. package/dist/sensors/gps-error-handler.d.ts +1 -1
  137. package/dist/sensors/gps.d.ts +1 -1
  138. package/dist/sensors/index.d.ts +4 -4
  139. package/dist/sensors/permission-checker.d.ts +1 -1
  140. package/dist/{session-disposers-BZS-hi8u.js → session-disposers-BJM5U62W.js} +1 -1
  141. package/dist/state/app-selectors.d.ts +1 -1
  142. package/dist/state/combined-root-state.d.ts +1 -1
  143. package/dist/state/create-slam-app-store.d.ts +1 -1
  144. package/dist/state/create-slam-app-store.js +1 -1
  145. package/dist/state/gps-ar-pose-sampler.d.ts +2 -2
  146. package/dist/state/gps-event-coordinator.d.ts +2 -2
  147. package/dist/state/index.d.ts +19 -20
  148. package/dist/state/index.js +3 -4
  149. package/dist/state/persistence-middleware.d.ts +2 -2
  150. package/dist/state/persistence-middleware.js +24 -15
  151. package/dist/state/qr-detected-slice.d.ts +3 -3
  152. package/dist/state/qr-detected-slice.js +8 -8
  153. package/dist/state/recording-replayer.d.ts +2 -2
  154. package/dist/state/recording-replayer.js +1 -1
  155. package/dist/state/recording-slice.d.ts +1 -1
  156. package/dist/state/replay-engine.d.ts +1 -1
  157. package/dist/state/replay-occupancy-subscriber.d.ts +51 -0
  158. package/dist/state/replay-occupancy-subscriber.js +85 -0
  159. package/dist/state/replay-session.d.ts +88 -0
  160. package/dist/state/replay-session.js +165 -0
  161. package/dist/state/store-subscribers.d.ts +2 -2
  162. package/dist/state/store-subscribers.js +1 -1
  163. package/dist/state/subscribe-to-selector.d.ts +1 -1
  164. package/dist/state/tracking-quality.d.ts +1 -1
  165. package/dist/state/tracking-quality.js +2 -2
  166. package/dist/state/tracking-slice.d.ts +1 -1
  167. package/dist/{state-U45ioVyB.js → state-DxL3T1Id.js} +1 -2
  168. package/dist/storage/file-system-utils.d.ts +1 -1
  169. package/dist/storage/file-system-utils.js +1 -1
  170. package/dist/storage/index.d.ts +8 -8
  171. package/dist/storage/null-storage-backend.d.ts +1 -1
  172. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  173. package/dist/storage/opfs-storage.d.ts +1 -1
  174. package/dist/storage/storage-backend.d.ts +1 -1
  175. package/dist/storage/zip-coverage-embed.d.ts +1 -1
  176. package/dist/storage/zip-coverage-embed.js +1 -1
  177. package/dist/storage/zip-export.d.ts +1 -1
  178. package/dist/storage/zip-reader.d.ts +1 -1
  179. package/dist/{storage-backend-BX7egQKi.d.ts → storage-backend-DCYbOvTw.d.ts} +1 -1
  180. package/dist/{store-subscribers-DtwakLrQ.d.ts → store-subscribers-BbRW35u5.d.ts} +2 -2
  181. package/dist/{subscribe-to-selector-Cgo9JTfS.d.ts → subscribe-to-selector-B_lm_euO.d.ts} +1 -1
  182. package/dist/test-utils/browser-mocks.d.ts +1 -1
  183. package/dist/test-utils/zip-round-trip-helpers.d.ts +1 -1
  184. package/dist/text-sprite-C6VcC2mo.d.ts +53 -0
  185. package/dist/{tracking-slice-Bt2OEQhA.d.ts → tracking-slice-D5LDL_y4.d.ts} +3 -2
  186. package/dist/types/ar-types.d.ts +1 -1
  187. package/dist/types/geo-types.d.ts +1 -1
  188. package/dist/types/index.d.ts +2 -2
  189. package/dist/utils/concurrency.d.ts +1 -1
  190. package/dist/utils/failure-tracker.d.ts +1 -1
  191. package/dist/utils/format-file-size.d.ts +1 -1
  192. package/dist/utils/fused-path.d.ts +1 -1
  193. package/dist/utils/index.d.ts +7 -7
  194. package/dist/utils/index.js +1 -1
  195. package/dist/utils/list-formatter.d.ts +1 -1
  196. package/dist/utils/logger.d.ts +1 -1
  197. package/dist/visualization/accuracy-circles.d.ts +1 -1
  198. package/dist/visualization/accuracy-circles.js +1 -1
  199. package/dist/visualization/alignment-lerper.d.ts +1 -1
  200. package/dist/visualization/ar-world-group-alignment.d.ts +1 -1
  201. package/dist/visualization/ar-world-group-alignment.js +2 -2
  202. package/dist/visualization/camera-follower.d.ts +1 -1
  203. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  204. package/dist/visualization/frame-conversions.d.ts +1 -1
  205. package/dist/visualization/frustum-visibility.d.ts +1 -1
  206. package/dist/visualization/gps-anchor.d.ts +1 -1
  207. package/dist/visualization/gps-anchor.js +2 -2
  208. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  209. package/dist/visualization/gps-compass-cubes.js +6 -22
  210. package/dist/visualization/gps-event-markers.d.ts +2 -2
  211. package/dist/visualization/gps-event-markers.js +27 -6
  212. package/dist/visualization/hit-test-reticle.d.ts +1 -1
  213. package/dist/visualization/hit-test-reticle.js +3 -2
  214. package/dist/visualization/index.d.ts +25 -20
  215. package/dist/visualization/index.js +11 -6
  216. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  217. package/dist/visualization/leaflet-map-overlay.js +1 -1
  218. package/dist/visualization/lerp-utils.d.ts +1 -1
  219. package/dist/visualization/map-data.d.ts +1 -1
  220. package/dist/visualization/map-data.js +1 -1
  221. package/dist/visualization/map-overlay-draw.d.ts +1 -1
  222. package/dist/visualization/occluder-mesh-driver.d.ts +2 -2
  223. package/dist/visualization/occluder-mesh-driver.js +1 -1
  224. package/dist/visualization/occlusion-mesh.d.ts +2 -2
  225. package/dist/visualization/occlusion-mesh.js +54 -4
  226. package/dist/visualization/occupancy-cubes-visualizer.d.ts +2 -0
  227. package/dist/visualization/occupancy-cubes-visualizer.js +221 -0
  228. package/dist/visualization/perf-stats-overlay.d.ts +2 -0
  229. package/dist/visualization/perf-stats-overlay.js +85 -0
  230. package/dist/visualization/pointer-picking.d.ts +2 -0
  231. package/dist/visualization/pointer-picking.js +58 -0
  232. package/dist/visualization/text-sprite.d.ts +2 -0
  233. package/dist/visualization/text-sprite.js +105 -0
  234. package/dist/visualization/three-dispose.d.ts +1 -1
  235. package/dist/visualization/vis-colors.d.ts +1 -1
  236. package/dist/visualization/wayfinding-hud.d.ts +2 -0
  237. package/dist/visualization/wayfinding-hud.js +289 -0
  238. package/dist/visualization/wayfinding-placement.d.ts +2 -0
  239. package/dist/visualization/wayfinding-placement.js +157 -0
  240. package/dist/wayfinding-hud-DVun2b69.d.ts +82 -0
  241. package/dist/wayfinding-placement-dnHzfYlT.d.ts +97 -0
  242. package/dist/{webxr-session-DWKUsCN9.js → webxr-session-BBlgzrqY.js} +150 -280
  243. package/dist/{webxr-session-CGFZ429B.d.ts → webxr-session-DurXRnl_.d.ts} +144 -194
  244. package/dist/{xr-frame-loop-25gM4B0K.d.ts → xr-frame-loop-A1mGDFHI.d.ts} +1 -1
  245. package/dist/{zip-coverage-embed-BrodRLq0.d.ts → zip-coverage-embed-BC3O2-8b.d.ts} +1 -1
  246. package/package.json +5 -3
  247. package/dist/ar/qr-debug-view.d.ts +0 -2
  248. package/dist/ar/qr-detection-controller.js +0 -2
  249. package/dist/ar/qr-size-depth-context.d.ts +0 -3
  250. package/dist/ar/qr-size-measurer.js +0 -2
  251. package/dist/capture-motion-gate-BmjiWUJv.d.ts +0 -24
  252. package/dist/map-overlay-0yJOcEVO.d.ts +0 -153
  253. package/dist/recording-options-Cai9D14V.d.ts +0 -700
  254. package/dist/state/recording-options.d.ts +0 -2
  255. package/dist/state/recording-options.js +0 -620
  256. package/dist/visualization/map-overlay.d.ts +0 -2
  257. package/dist/visualization/map-overlay.js +0 -241
  258. /package/dist/{alignment-lerper-B4COh_0p.d.ts → alignment-lerper-CK1TYLIL.d.ts} +0 -0
  259. /package/dist/{ar-types-CBafnxhE.d.ts → ar-types-BprL3nKv.d.ts} +0 -0
  260. /package/dist/{bresenham3d-D-t9i_b5.d.ts → bresenham3d-bt61R-Qa.d.ts} +0 -0
  261. /package/dist/{camera-blit-capture-BlC-arRb.d.ts → camera-blit-capture-CgNJ9grH.d.ts} +0 -0
  262. /package/dist/{camera-follower-B6zA3dy9.d.ts → camera-follower-OnnXsbHd.d.ts} +0 -0
  263. /package/dist/{capture-failure-tracker-BAUKjtXU.d.ts → capture-failure-tracker-bUXJeMvQ.d.ts} +0 -0
  264. /package/dist/{concurrency-DW0jQo3G.d.ts → concurrency-CMhbkxBk.d.ts} +0 -0
  265. /package/dist/{css3d-renderer-manager-DbrSY7Mh.d.ts → css3d-renderer-manager-CE6xN7XM.d.ts} +0 -0
  266. /package/dist/{failure-tracker-B7fzPfZo.d.ts → failure-tracker-BdaFulDA.d.ts} +0 -0
  267. /package/dist/{format-file-size-Da8rZgfs.d.ts → format-file-size-B2CJdRqD.d.ts} +0 -0
  268. /package/dist/{frame-loop-7HigCj7m.d.ts → frame-loop-CUEIdlhS.d.ts} +0 -0
  269. /package/dist/{frustum-visibility-COPfzruF.d.ts → frustum-visibility-BTx1Sqfo.d.ts} +0 -0
  270. /package/dist/{geo-types-BfDK8kJu.d.ts → geo-types-DGe5UKgx.d.ts} +0 -0
  271. /package/dist/{gps-CX5b9g3s.d.ts → gps-CC0l9lCp.d.ts} +0 -0
  272. /package/dist/{gps-compass-cubes-CT3TWctJ.d.ts → gps-compass-cubes-QQJgpRXR.d.ts} +0 -0
  273. /package/dist/{gps-error-handler-DjVuLXve.d.ts → gps-error-handler-da4DCcs5.d.ts} +0 -0
  274. /package/dist/{hit-test-reticle-DhnCMOsc.d.ts → hit-test-reticle-DcOyqo3B.d.ts} +0 -0
  275. /package/dist/{index-CjxbDm8W.d.ts → index-T8Fxvzka.d.ts} +0 -0
  276. /package/dist/{index-Nr3qg4IH.d.ts → index-Y_RNWbQX.d.ts} +0 -0
  277. /package/dist/{lerp-utils-bwMwVCpU.d.ts → lerp-utils-B-ecvLq2.d.ts} +0 -0
  278. /package/dist/{list-formatter-1ttG18MQ.d.ts → list-formatter-C45u3Vgv.d.ts} +0 -0
  279. /package/dist/{logger-B4StJUDb.d.ts → logger-BQGNXi9W.d.ts} +0 -0
  280. /package/dist/{opfs-storage-S_odkCk1.d.ts → opfs-storage-CrhVauNL.d.ts} +0 -0
  281. /package/dist/{permission-checker-D1C5zvo-.d.ts → permission-checker-BDrCOwQF.d.ts} +0 -0
  282. /package/dist/{scene-node-names-DWzhE7Ro.d.ts → scene-node-names-Ct6ATrfM.d.ts} +0 -0
  283. /package/dist/{three-dispose-C9mdpSRX.d.ts → three-dispose-B5-XiECx.d.ts} +0 -0
  284. /package/dist/{vis-colors-DjStl_tD.d.ts → vis-colors-16Pht13u.d.ts} +0 -0
  285. /package/dist/{webxr-nue-basis-C3vTqkE2.d.ts → webxr-nue-basis-B8ZEetVb.d.ts} +0 -0
  286. /package/dist/{xr-camera-texture-C6Z4d7RR.d.ts → xr-camera-texture-BA4xiaQ4.d.ts} +0 -0
  287. /package/dist/{xr-error-handler-D9y5r8ok.d.ts → xr-error-handler-BeyxXCE_.d.ts} +0 -0
  288. /package/dist/{zip-export-CuBimX1J.d.ts → zip-export-Cfl_kNQ7.d.ts} +0 -0
  289. /package/dist/{zip-reader-BHc_b_iA.d.ts → zip-reader-DwkuvlGo.d.ts} +0 -0
@@ -2,7 +2,7 @@ import { trackingReducer } from "./state/tracking-slice.js";
2
2
  import { recordWriteFailure, recordingReducer } from "./state/recording-slice.js";
3
3
  import { createTrackingQualityListenerMiddleware, trackingQualityReducer } from "./state/tracking-quality.js";
4
4
  import { createPersistenceMiddleware, slicePrefixOf } from "./state/persistence-middleware.js";
5
- import { arElementsReducer, gpsDataReducer, gpsElementsReducer, sanitizeForDevTools, setColdStartOverrideEnabled, setCompassRotationPriorEnabled, setCompassWebXRConsistencyEnabled, setZeroPos, validateLicenseKey } from "gps-plus-slam-js";
5
+ import { arElementsReducer, gpsDataReducer, gpsElementsReducer, sanitizeForDevTools, setColdStartOverrideEnabled, setCompassExperimentEnabled, setCompassRotationPriorEnabled, setCompassWebXRConsistencyEnabled, setRobustSolverComparisonEnabled, setZeroPos, validateLicenseKey } from "gps-plus-slam-js";
6
6
  import { configureStore, createListenerMiddleware } from "@reduxjs/toolkit";
7
7
  import { COMMUNITY_LICENSE_KEY } from "gps-plus-slam-js/community-license-key";
8
8
  //#region ../src/state/slam-app-store-listener.ts
@@ -77,8 +77,9 @@ function createSlamAppStoreListenerMiddleware(optIns) {
77
77
  * never references those concepts so apps that don't need them (POI viewers,
78
78
  * navigation arrows, …) compose freely.
79
79
  *
80
- * The legacy `createRecorderStore` from `store.ts` is built on top of this
81
- * factory and will move out of the framework in Iter 1D.
80
+ * This is the framework's ONLY store factory (the legacy
81
+ * `createRecorderStore`/`store.ts` it replaced moved out in Iter 1D); the
82
+ * core library's license error messages point here as the remediation.
82
83
  *
83
84
  * @see docs/2026-05-03-appframework-vs-recorderapp-boundary-analysis.md — Iter 1
84
85
  */
@@ -95,7 +96,7 @@ const BUILTIN_PERSISTED_PREFIXES = [slicePrefixOf(setZeroPos.type), slicePrefixO
95
96
  * design rationale.
96
97
  */
97
98
  function createSlamAppStore(options) {
98
- const { storageBackend, extraReducers, extraMiddleware, persistedExtraPrefixes, onWriteFailure, enableDevChecks = true, licenseKey = COMMUNITY_LICENSE_KEY, trackingQualityOptions, enableCompassColdStartOverride = true, enableCompassRotationPrior = false, enableCompassWebXRConsistency = false } = options;
99
+ const { storageBackend, extraReducers, extraMiddleware, persistedExtraPrefixes, onWriteFailure, enableDevChecks = true, licenseKey = COMMUNITY_LICENSE_KEY, trackingQualityOptions, enableCompassColdStartOverride = true, enableCompassRotationPrior = false, enableCompassWebXRConsistency = false, enableCompassExperiment = false, enableRobustSolverComparison = false } = options;
99
100
  validateLicenseKey(licenseKey);
100
101
  const builtins = {
101
102
  gpsData: gpsDataReducer,
@@ -127,18 +128,27 @@ function createSlamAppStore(options) {
127
128
  isSet: (s) => s.gpsData?.compassWebXRConsistencyEnabled === true,
128
129
  apply: (dispatch) => dispatch(setCompassWebXRConsistencyEnabled(true))
129
130
  });
131
+ if (enableCompassExperiment) compassOptIns.push({
132
+ isSet: (s) => s.gpsData?.compassExperimentEnabled === true,
133
+ apply: (dispatch) => dispatch(setCompassExperimentEnabled(true))
134
+ });
135
+ if (enableRobustSolverComparison) compassOptIns.push({
136
+ isSet: (s) => s.gpsData?.robustSolverComparisonEnabled === true,
137
+ apply: (dispatch) => dispatch(setRobustSolverComparisonEnabled(true))
138
+ });
130
139
  const prependedListeners = [trackingQualityMiddleware];
131
140
  if (compassOptIns.length > 0) prependedListeners.push(createSlamAppStoreListenerMiddleware(compassOptIns));
141
+ const persistenceMiddleware = createPersistenceMiddleware({
142
+ storageBackend,
143
+ onWriteFailure,
144
+ persistedPrefixes: [...BUILTIN_PERSISTED_PREFIXES, ...persistedExtraPrefixes ?? []]
145
+ });
132
146
  const store = configureStore({
133
147
  reducer,
134
148
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({
135
149
  serializableCheck: enableDevChecks ? { ignoredActions: ["tracking/poseReceived"] } : false,
136
150
  immutableCheck: enableDevChecks ? { ignoredPaths: ["tracking"] } : false
137
- }).prepend(...prependedListeners).concat(createPersistenceMiddleware({
138
- storageBackend,
139
- onWriteFailure,
140
- persistedPrefixes: [...BUILTIN_PERSISTED_PREFIXES, ...persistedExtraPrefixes ?? []]
141
- }), ...extraMiddleware ?? []),
151
+ }).prepend(...prependedListeners).concat(persistenceMiddleware, ...extraMiddleware ?? []),
142
152
  devTools: {
143
153
  actionSanitizer: sanitizeForDevTools,
144
154
  stateSanitizer: sanitizeForDevTools
@@ -149,7 +159,8 @@ function createSlamAppStore(options) {
149
159
  dispatch: store.dispatch,
150
160
  subscribe: (listener) => store.subscribe(listener),
151
161
  writeFrame: (blob, index) => storageBackend.writeFrame(blob, index),
152
- writeSessionMetadata: (metadata) => storageBackend.writeSessionMetadata(metadata)
162
+ writeSessionMetadata: (metadata) => storageBackend.writeSessionMetadata(metadata),
163
+ flushPendingActionWrites: () => persistenceMiddleware.flushPendingWrites()
153
164
  };
154
165
  }
155
166
  //#endregion
@@ -1,4 +1,4 @@
1
- import { r as DepthPoint } from "./ar-types-CBafnxhE.js";
1
+ import { r as DepthPoint } from "./ar-types-BprL3nKv.js";
2
2
 
3
3
  //#region ../src/ar/depth-grid-lookup.d.ts
4
4
  interface DepthGridLookup {
@@ -1,4 +1,4 @@
1
- import { a as RgbTuple, i as DepthSample, t as ARPose } from "./ar-types-CBafnxhE.js";
1
+ import { a as RgbTuple, i as DepthSample, t as ARPose } from "./ar-types-BprL3nKv.js";
2
2
  import { Matrix4 } from "gps-plus-slam-js";
3
3
 
4
4
  //#region ../src/ar/depth-rgb-lookup.d.ts
@@ -72,7 +72,7 @@ interface DepthInfo {
72
72
  * the matrices: the per-frame buffer is too large to clone and the live
73
73
  * depth occluder uploads it synchronously). Absent when the source carries
74
74
  * no `data` (e.g. the sparse-only path). Plumbed for the live depth occluder
75
- * (2026-06-14-webxr-depth-occlusion-plan.md §2); the sparse sampler ignores it.
75
+ * (2026-06-14-0009-webxr-depth-occlusion-plan.md §2); the sparse sampler ignores it.
76
76
  */
77
77
  data?: ArrayBuffer;
78
78
  /**
@@ -114,6 +114,33 @@ declare function wrapXRDepthInfo(raw: {
114
114
  matrix?: ArrayLike<number>;
115
115
  } | null;
116
116
  }, projectionMatrix: ArrayLike<number> | undefined): DepthInfo;
117
+ /**
118
+ * Recommended depth-sampling cadence for apps that RECONSTRUCT-and-render an
119
+ * occupancy mesh (the Recorder, the PhysicsDemo) — the depth-side counterpart
120
+ * of `DEFAULT_OCCUPANCY_CELL_SIZE_M`/`DEFAULT_OCCUPANCY_MIN_OBSERVATIONS`
121
+ * (occupancy-grid.ts): one framework-level source of truth so both apps build
122
+ * the mesh at the same speed (2026-07-16 field feedback: the demo relied on
123
+ * the conservative fallback below — 16×16 @ 1 Hz, 8× fewer points/s than the
124
+ * recorder — and reconstructed visibly slower).
125
+ *
126
+ * Tuning (2026-07-16 EVENING, maintainer's on-device framerate/mesh trade-off
127
+ * passes — supersedes the same-day sweep-derived 500 ms × 64): 200 ms × 24×24.
128
+ * The ground-truth density/cadence sweep
129
+ * (GpsPlusSlamJs_Investigation test-results/synthetic-density-cadence-sweep.txt)
130
+ * showed density is the more point-efficient mesh-speed lever, but its
131
+ * flagged open question — on-device frame-time cost — resolved against LARGE
132
+ * per-sample batches: 64² @ 2 Hz (8192 points/s) visibly hurt the framerate,
133
+ * while many SMALL samples (24² @ 5 Hz, ~2880 points/s) keep the per-frame
134
+ * work chunk tiny and rendering smooth at good mesh build-up. If devices get
135
+ * faster, the sweep says gridSize (not the interval) is the knob to raise
136
+ * first.
137
+ *
138
+ * Deliberately OPT-IN named constants, NOT a change to the fallback below:
139
+ * bumping the fallback would silently re-tune consumers that are not
140
+ * reconstruction apps (MinimalExample / AnchorStarter).
141
+ */
142
+ declare const DEFAULT_RECONSTRUCTION_DEPTH_INTERVAL_MS = 200;
143
+ declare const DEFAULT_RECONSTRUCTION_DEPTH_GRID_SIZE = 24;
117
144
  /**
118
145
  * Samples sparse depth points from WebXR depth sensing.
119
146
  *
@@ -208,4 +235,4 @@ declare class DepthSampler {
208
235
  hasReceivedDepth(): boolean;
209
236
  }
210
237
  //#endregion
211
- export { wrapXRDepthInfo as a, DepthSamplerConfig as i, DepthSampler as n, DepthSamplerCallbacks as r, DepthInfo as t };
238
+ export { DepthSamplerCallbacks as a, DepthSampler as i, DEFAULT_RECONSTRUCTION_DEPTH_INTERVAL_MS as n, DepthSamplerConfig as o, DepthInfo as r, wrapXRDepthInfo as s, DEFAULT_RECONSTRUCTION_DEPTH_GRID_SIZE as t };
@@ -1,4 +1,4 @@
1
- import { r as DepthPoint } from "./ar-types-CBafnxhE.js";
1
+ import { r as DepthPoint } from "./ar-types-BprL3nKv.js";
2
2
  import { Matrix4, Quaternion, Vector3 } from "gps-plus-slam-js";
3
3
 
4
4
  //#region ../src/ar/depth-unprojection.d.ts
@@ -1,7 +1,7 @@
1
- import { t as ArCrashIsolationOptions } from "./recording-options-Cai9D14V.js";
2
- import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-CX5b9g3s.js";
3
- import { n as PermissionStatus } from "./permission-checker-D1C5zvo-.js";
4
- import { s as SessionFeatureOptions } from "./webxr-session-CGFZ429B.js";
1
+ import { t as ArCrashIsolationOptions } from "./ar-crash-isolation-BSFw_beO.js";
2
+ import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-CC0l9lCp.js";
3
+ import { n as PermissionStatus } from "./permission-checker-BDrCOwQF.js";
4
+ import { a as SessionFeatureOptions, t as ArSessionCallbacks } from "./webxr-session-DurXRnl_.js";
5
5
 
6
6
  //#region ../src/ar/enable-gps-ar.d.ts
7
7
  /**
@@ -37,6 +37,11 @@ interface EnableGpsArConfig {
37
37
  requestHitTest?: boolean;
38
38
  /** Crash-isolation diagnostic flags forwarded verbatim to `initAR`. */
39
39
  isolationOptions?: Partial<ArCrashIsolationOptions>;
40
+ /**
41
+ * Per-session AR callbacks (tracking store, depth, image capture, …)
42
+ * forwarded verbatim to `initAR` — see {@link ArSessionCallbacks}.
43
+ */
44
+ callbacks?: ArSessionCallbacks;
40
45
  /** Receives every GPS fix from the started watch. */
41
46
  onGpsPosition?: (position: GpsPosition) => void;
42
47
  /** Receives every device-orientation sample from the started watch. */
@@ -56,7 +61,7 @@ interface EnableGpsArDeps {
56
61
  requestWebXRWithDepthPermission: () => Promise<PermissionStatus>;
57
62
  startGpsWatch: (onPosition: (position: GpsPosition) => void, onError?: (error: GeolocationPositionError) => void) => void;
58
63
  startOrientationWatch: (onOrientation: (orientation: RawDeviceOrientation) => void) => void;
59
- initAR: (container: HTMLElement, isolationOptions?: Partial<ArCrashIsolationOptions>, sessionFeatures?: SessionFeatureOptions) => Promise<void>;
64
+ initAR: (container: HTMLElement, isolationOptions?: Partial<ArCrashIsolationOptions>, sessionFeatures?: SessionFeatureOptions, callbacks?: ArSessionCallbacks) => Promise<void>;
60
65
  stopGpsWatch: () => void;
61
66
  stopOrientationWatch: () => void;
62
67
  endARSession: () => Promise<void>;
@@ -26,7 +26,7 @@ declare function formatFrameFilename(index: number): string;
26
26
  * is a textbook COLMAP tree (`images/frame-NNNNNN.jpg` next to `sparse/0/`).
27
27
  * Both the OPFS write path and the recorder's persisted `imageFile` value must
28
28
  * use THIS constant so a recording stays self-consistent (COLMAP export plan
29
- * Q5, gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-13-colmap-export-plan.md).
29
+ * Q5, gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-13-1205-colmap-export-plan.md).
30
30
  */
31
31
  declare const SESSION_IMAGES_DIR = "images";
32
32
  /**
@@ -1,4 +1,4 @@
1
- import { i as LatLongAlt, r as LatLong } from "./index-CjxbDm8W.js";
1
+ import { i as LatLongAlt, r as LatLong } from "./index-T8Fxvzka.js";
2
2
  import * as THREE from "three";
3
3
 
4
4
  //#region ../src/visualization/frame-conversions.d.ts
@@ -1,4 +1,4 @@
1
- import { t as GpsCoord } from "./geo-types-BfDK8kJu.js";
1
+ import { t as GpsCoord } from "./geo-types-DGe5UKgx.js";
2
2
  import { LatLong, Matrix4, Vector3, fusedGpsFromOdom } from "gps-plus-slam-js";
3
3
 
4
4
  //#region ../src/utils/fused-path.d.ts
@@ -1,2 +1,2 @@
1
- import { a as findNearbyGeoAnchor, c as h3CellsMatch, i as clusterCellsByZoom, l as isH3Index, n as KnownGeoAnchor, o as gpsPathToCoverageCells, r as approxDistanceMetres, s as gpsToH3, t as H3_RESOLUTION } from "../h3-proximity-pFluGfwL.js";
1
+ import { a as findNearbyGeoAnchor, c as h3CellsMatch, i as clusterCellsByZoom, l as isH3Index, n as KnownGeoAnchor, o as gpsPathToCoverageCells, r as approxDistanceMetres, s as gpsToH3, t as H3_RESOLUTION } from "../h3-proximity-CAEk3osq.js";
2
2
  export { H3_RESOLUTION, KnownGeoAnchor, approxDistanceMetres, clusterCellsByZoom, findNearbyGeoAnchor, gpsPathToCoverageCells, gpsToH3, h3CellsMatch, isH3Index };
@@ -51,7 +51,7 @@ function gpsPathToCoverageCells(path) {
51
51
  * truncate the hex-string id: resolution is encoded in the high bits with
52
52
  * trailing `f` padding, so slicing yields INVALID cells, not parents (verified;
53
53
  * see the D1 gotcha in
54
- * docs/2026-06-14-map-centric-recording-browser-and-h3-index-user-feedback.md).
54
+ * docs/2026-06-14-1048-map-centric-recording-browser-and-h3-index-user-feedback.md).
55
55
  *
56
56
  * `targetRes` is clamped to `[0, H3_RESOLUTION]` because `cellToParent` throws
57
57
  * when asked for a FINER resolution than the cell, and res 11 is the finest
@@ -1,2 +1,2 @@
1
- import { a as findNearbyGeoAnchor, c as h3CellsMatch, i as clusterCellsByZoom, l as isH3Index, n as KnownGeoAnchor, o as gpsPathToCoverageCells, r as approxDistanceMetres, s as gpsToH3, t as H3_RESOLUTION } from "../h3-proximity-pFluGfwL.js";
1
+ import { a as findNearbyGeoAnchor, c as h3CellsMatch, i as clusterCellsByZoom, l as isH3Index, n as KnownGeoAnchor, o as gpsPathToCoverageCells, r as approxDistanceMetres, s as gpsToH3, t as H3_RESOLUTION } from "../h3-proximity-CAEk3osq.js";
2
2
  export { H3_RESOLUTION, type KnownGeoAnchor, approxDistanceMetres, clusterCellsByZoom, findNearbyGeoAnchor, gpsPathToCoverageCells, gpsToH3, h3CellsMatch, isH3Index };
@@ -5,14 +5,14 @@ import { quat } from "gl-matrix";
5
5
  * rotation angle between two unit quaternions.
6
6
  *
7
7
  * This used to be hand-rolled in (at least) two places:
8
- * - `geodesicAngleRad` (private) in `ar/qr-pose-aggregation.ts`, and
8
+ * - `geodesicAngleRad` (private) in `ar/qr/qr-pose-aggregation.ts`, and
9
9
  * - `quat.getAngle(...)` + a NaN guard inside `state/tracking-quality.ts`'s
10
10
  * `matrixDelta`.
11
11
  *
12
12
  * Both compute the same number — `acos(2·dot² − 1)` — so they are consolidated
13
13
  * here so a third consumer (the capture motion gate's angular-velocity helper,
14
14
  * `ar/pose-motion.ts`) reuses one definition instead of adding a fourth copy.
15
- * See `GpsPlusSlamJs_Docs/docs/2026-06-23-followup-consolidate-geodesic-angle-kernel.md`.
15
+ * See `GpsPlusSlamJs_Docs/docs/2026-06-23-2120-consolidate-geodesic-angle-kernel-followup.md`.
16
16
  */
17
17
  /**
18
18
  * Geodesic (shortest-arc) rotation angle in radians between two **unit**
@@ -1,4 +1,4 @@
1
- import { i as LatLongAlt, r as LatLong } from "./index-CjxbDm8W.js";
1
+ import { i as LatLongAlt, r as LatLong } from "./index-T8Fxvzka.js";
2
2
  import * as THREE from "three";
3
3
 
4
4
  //#region ../src/visualization/gps-anchor.d.ts
@@ -1,4 +1,4 @@
1
- import { t as ARPose } from "./ar-types-CBafnxhE.js";
1
+ import { t as ARPose } from "./ar-types-BprL3nKv.js";
2
2
  import { Quaternion, Vector3 } from "gps-plus-slam-js";
3
3
 
4
4
  //#region ../src/state/gps-ar-pose-sampler.d.ts
@@ -1,7 +1,7 @@
1
- import { t as ARPose } from "./ar-types-CBafnxhE.js";
2
- import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-CX5b9g3s.js";
3
- import { t as AbsoluteOrientationReading } from "./absolute-orientation-C_IxDR_j.js";
4
- import { i as SlamAppStore } from "./create-slam-app-store-CH31erpP.js";
1
+ import { t as ARPose } from "./ar-types-BprL3nKv.js";
2
+ import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-CC0l9lCp.js";
3
+ import { t as AbsoluteOrientationReading } from "./absolute-orientation-0WIsqJnu.js";
4
+ import { i as SlamAppStore } from "./create-slam-app-store-HNe1PBtx.js";
5
5
  import { RawAbsoluteOrientation, RawGpsPoint, RecordGpsEventPayload, eulerToQuaternion } from "gps-plus-slam-js";
6
6
  import { ReducersMapObject } from "@reduxjs/toolkit";
7
7
 
@@ -1,6 +1,26 @@
1
- import { LatLong, Vector3 } from "gps-plus-slam-js";
1
+ import * as THREE from "three";
2
+ import { LatLong, Vector3 as Vector3$1 } from "gps-plus-slam-js";
2
3
 
3
4
  //#region ../src/visualization/gps-event-markers.d.ts
5
+ /**
6
+ * Where the visualizer resolves its scene graph from.
7
+ *
8
+ * By default markers are parented into the LIVE AR session's scene
9
+ * (`webxr-session.ts` getters). Non-live consumers (desktop replay, offline
10
+ * e2e fixtures) point the visualizer at their own scene via
11
+ * {@link GpsEventVisualizer.setSceneSource} instead of injecting their scene
12
+ * into the webxr-session singleton (the deleted replay-mode "Risk R1" setters
13
+ * — see the 2026-07-11 webxr-session surface-reduction plan, step 2).
14
+ *
15
+ * Both functions may return `null` (e.g. before `initAR()`); the visualizer
16
+ * then warns and skips the affected marker, exactly as before.
17
+ */
18
+ interface GpsMarkerSceneSource {
19
+ /** Scene root — parents raw-GPS (yellow) and snapshot (red) markers. */
20
+ getScene: () => THREE.Scene | null;
21
+ /** AR world group — parents fused (cyan) markers so they ride the alignment. */
22
+ getArWorldGroup: () => THREE.Group | null;
23
+ }
4
24
  /**
5
25
  * Optional GPS-accuracy hints used by {@link GpsEventVisualizer.addGpsEvent}
6
26
  * to render the raw-GPS marker as a non-uniform-scaled ellipsoid.
@@ -32,6 +52,20 @@ declare class GpsEventVisualizer {
32
52
  * Default `true` — the markers render exactly as before until opted out.
33
53
  */
34
54
  private markersVisible;
55
+ /**
56
+ * Scene graph the markers are parented into. Defaults to the live AR
57
+ * session ({@link LIVE_SCENE_SOURCE}); replay / offline consumers override
58
+ * it via {@link setSceneSource}. Not reset by {@link clearAll} — the owner
59
+ * of the non-live scene (e.g. replay-mode's dispose) restores the default.
60
+ */
61
+ private sceneSource;
62
+ /**
63
+ * Point the visualizer at a non-live scene graph (desktop replay, offline
64
+ * e2e fixture). Pass `null` to restore the live-session default. The caller
65
+ * that overrides the source is responsible for restoring it when its scene
66
+ * is disposed, so a later live AR session parents markers correctly again.
67
+ */
68
+ setSceneSource(source: GpsMarkerSceneSource | null): void;
35
69
  /**
36
70
  * Set the GPS zero reference (origin for coordinate conversion).
37
71
  * Must be called before adding GPS events.
@@ -56,18 +90,18 @@ declare class GpsEventVisualizer {
56
90
  * fixed 8 cm sphere (same defensive policy as `preview-map.ts`).
57
91
  * Cyan fused and red snapshot markers are never affected by this argument.
58
92
  */
59
- addGpsEvent(gpsCoords: Vector3, odomPosition: Vector3, accuracy?: GpsEventAccuracy): void;
93
+ addGpsEvent(gpsCoords: Vector3$1, odomPosition: Vector3$1, accuracy?: GpsEventAccuracy): void;
60
94
  /**
61
95
  * Add an alignment snapshot marker at the given NUE position.
62
96
  * Snapshots represent the system's best GPS estimate at each alignment update.
63
97
  * Added to scene root (GPS world space), not arWorldGroup.
64
98
  */
65
- addAlignmentSnapshot(nuePosition: Vector3): void;
99
+ addAlignmentSnapshot(nuePosition: Vector3$1): void;
66
100
  /**
67
101
  * Get the NUE positions of all alignment snapshot markers.
68
102
  * Used at session end to convert to GPS coordinates for the summary map.
69
103
  */
70
- getAlignmentSnapshotPositions(): Vector3[];
104
+ getAlignmentSnapshotPositions(): Vector3$1[];
71
105
  /**
72
106
  * Create a sphere marker mesh with the given color and name.
73
107
  */
@@ -118,4 +152,4 @@ declare class GpsEventVisualizer {
118
152
  */
119
153
  declare const gpsEventVisualizer: GpsEventVisualizer;
120
154
  //#endregion
121
- export { GpsEventVisualizer as n, gpsEventVisualizer as r, GpsEventAccuracy as t };
155
+ export { gpsEventVisualizer as i, GpsEventVisualizer as n, GpsMarkerSceneSource as r, GpsEventAccuracy as t };
@@ -52,7 +52,7 @@ declare function gpsPathToCoverageCells(path: readonly LatLngLike[]): string[];
52
52
  * truncate the hex-string id: resolution is encoded in the high bits with
53
53
  * trailing `f` padding, so slicing yields INVALID cells, not parents (verified;
54
54
  * see the D1 gotcha in
55
- * docs/2026-06-14-map-centric-recording-browser-and-h3-index-user-feedback.md).
55
+ * docs/2026-06-14-1048-map-centric-recording-browser-and-h3-index-user-feedback.md).
56
56
  *
57
57
  * `targetRes` is clamped to `[0, H3_RESOLUTION]` because `cellToParent` throws
58
58
  * when asked for a FINER resolution than the cell, and res 11 is the finest
@@ -0,0 +1,40 @@
1
+ import { Object3D, Vector3 } from "three";
2
+
3
+ //#region ../src/ar/hit-test-reticle-driver.d.ts
4
+ /** Live-reticle handle returned by {@link startHitTestReticle}. */
5
+ interface HitTestReticleHandle {
6
+ /** Is a surface currently under the screen-centre reticle? */
7
+ isVisible(): boolean;
8
+ /**
9
+ * Write the reticle's current world position into `out` and return it. Only
10
+ * meaningful while `isVisible()` is true; the value is the GPS-world (NUE)
11
+ * pose once `arWorldGroup` carries the alignment.
12
+ */
13
+ getWorldPosition(out: Vector3): Vector3;
14
+ /** Remove the reticle mesh and unregister the frame loop (idempotent). */
15
+ dispose(): void;
16
+ }
17
+ /** Arguments for {@link startHitTestReticle}. */
18
+ interface HitTestReticleArgs {
19
+ /**
20
+ * Parent for the reticle mesh — pass `getArWorldGroup()` so the reticle
21
+ * rides the GPS alignment and its world pose is GPS-world (NUE).
22
+ */
23
+ arWorldGroup: Object3D;
24
+ /**
25
+ * Optional tap handler, fired on EVERY WebXR `select` — with the reticle's
26
+ * current world position when a surface is present, or `null` when not.
27
+ * Surface-less taps are reported too so the app can react (GPS gating,
28
+ * "point at the floor" hints); the placement decision stays app-side.
29
+ * When omitted, no `select` listener is registered at all.
30
+ */
31
+ onSelect?: (worldPosition: Vector3 | null) => void;
32
+ }
33
+ /**
34
+ * Install the hit-test reticle under `arWorldGroup` and start driving it from
35
+ * the XR frame loop. Returns a handle the app reads at placement time (or
36
+ * ignores entirely when it placed via `onSelect`).
37
+ */
38
+ declare function startHitTestReticle(args: HitTestReticleArgs): HitTestReticleHandle;
39
+ //#endregion
40
+ export { HitTestReticleHandle as n, startHitTestReticle as r, HitTestReticleArgs as t };
@@ -1,6 +1,6 @@
1
- import { o as WebXRQuaternion, s as WebXRVec3, t as ARPose } from "./ar-types-CBafnxhE.js";
2
- import { t as MotionFilterConfig } from "./capture-motion-gate-BmjiWUJv.js";
3
- import { a as QualityFilterConfig } from "./image-quality-BjBLoTec.js";
1
+ import { i as MotionFilterConfig } from "./capture-motion-gate-C60Qrilh.js";
2
+ import { o as WebXRQuaternion, s as WebXRVec3, t as ARPose } from "./ar-types-BprL3nKv.js";
3
+ import { s as QualityFilterConfig } from "./image-quality-G7_qT4aj.js";
4
4
 
5
5
  //#region ../src/ar/image-capture.d.ts
6
6
  /**
@@ -51,7 +51,7 @@ declare const DEFAULT_CAPTURE_CONFIG: ImageCaptureConfig;
51
51
  * action by the RecorderApp's `handleImageCaptured`, which rebuilds the
52
52
  * payload field-by-field. A new field added here is therefore NOT persisted
53
53
  * until it is threaded through that handler — see
54
- * `2026-06-12-payload-rebuild-field-drop-audit.md` (F1/F2) and the forwarding
54
+ * `2026-06-12-1130-payload-rebuild-field-drop-audit.md` (F1/F2) and the forwarding
55
55
  * test in `main.occupancy-cubes-wiring.test.ts`.
56
56
  */
57
57
  interface CapturedImage {
@@ -83,7 +83,7 @@ interface CapturedImage {
83
83
  * A captured frame blob together with the pixel dimensions it was encoded at.
84
84
  * Returned by the optional `captureFrame` (blit) callback so the pose-invariant
85
85
  * image size can be persisted as first-class metadata (frame-tile aspect-ratio
86
- * fix, D1 of 2026-06-13-frame-tile-rendering-bugs-user-feedback.md). The
86
+ * fix, D1 of 2026-06-13-1311-frame-tile-rendering-bugs-user-feedback.md). The
87
87
  * dimensions are the blit render-target size — identical to the JPEG's own
88
88
  * width/height — so no decode is needed to learn the aspect ratio.
89
89
  */
@@ -148,7 +148,7 @@ interface ImageCaptureCallbacks {
148
148
  * callback MUST settle its promise; if it rejects, or does not settle within
149
149
  * `captureTimeoutMs`, the manager fails open (saves the frame) so a hung
150
150
  * analyzer cannot deadlock the pipeline. See `image-quality.ts` and
151
- * `GpsPlusSlamJs_Docs/docs/2026-06-24-image-quality-gate-plan.md`.
151
+ * `GpsPlusSlamJs_Docs/docs/2026-06-24-1057-image-quality-gate-plan.md`.
152
152
  */
153
153
  analyzeFrame?: (frame: CapturedFrame) => Promise<FrameQualityVerdict>;
154
154
  }
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from "./utils/logger.js";
2
- import { t as geodesicAngleRad } from "./geodesic-angle-HXBWiXiI.js";
3
- import { n as MotionWindow, r as decideCapture, t as DEFAULT_MOTION_FILTER } from "./capture-motion-gate-D1eyGC_o.js";
2
+ import { t as geodesicAngleRad } from "./geodesic-angle-CZ_Ow90I.js";
3
+ import { DEFAULT_MOTION_FILTER, MotionWindow, decideCapture } from "./ar/capture-motion-gate.js";
4
4
  import { DEFAULT_QUALITY_FILTER } from "./ar/image-quality.js";
5
5
  import { quat } from "gl-matrix";
6
6
  //#region ../src/ar/pose-motion.ts
@@ -8,7 +8,7 @@ import { quat } from "gl-matrix";
8
8
  * Pose-motion helpers — stateless angular/linear velocity from two AR poses.
9
9
  *
10
10
  * The capture motion gate (blurry-frame skipping, see
11
- * `GpsPlusSlamJs_Docs/docs/2026-06-23-blurry-frame-motion-gating-plan.md` §4.1)
11
+ * `GpsPlusSlamJs_Docs/docs/2026-06-23-2105-blurry-frame-motion-gating-plan.md` §4.1)
12
12
  * rejects frames whose device motion is too fast to yield a sharp image. Motion
13
13
  * is derived from consecutive WebXR poses — cheaper than any image-content
14
14
  * metric because it needs no GPU readback.
@@ -21,10 +21,23 @@
21
21
  * black/empty frame; an absolute cutoff is safe because "black is black"
22
22
  * regardless of scene texture (§5).
23
23
  *
24
- * @see GpsPlusSlamJs_Docs/docs/2026-06-24-image-quality-gate-plan.md
24
+ * @see GpsPlusSlamJs_Docs/docs/2026-06-24-1057-image-quality-gate-plan.md
25
25
  * @see ./capture-motion-gate.ts — the motion gate this builds on (same shape:
26
26
  * a shared config type + a small stateful window + a pure decision).
27
27
  */
28
+ /**
29
+ * Selectable sharpness metrics for the gate's blur check. Both are pure
30
+ * grayscale scorers with identical defensive contracts; the gate's RELATIVE
31
+ * rule (`score < k · median(recent)`) is metric-agnostic, so the same
32
+ * `blurRelativeThreshold` slider drives either. Benchmarked against the
33
+ * hand-labeled recording 2026-07-11 (variance-of-Laplacian best at "clearly
34
+ * blurry vs rest", the energy ratio best at "sharp vs degraded") — see
35
+ * GpsPlusSlamJs_Docs/docs/2026-07-12-0823-blur-metric-toggle-plan.md.
36
+ */
37
+ type BlurMetricId = 'variance-of-laplacian' | 'high-frequency-energy-ratio';
38
+ /** All valid {@link BlurMetricId} values, the default (VoL) first — for
39
+ * consumer-side validation of persisted configs. */
40
+ declare const BLUR_METRIC_IDS: readonly BlurMetricId[];
28
41
  /**
29
42
  * User-/consumer-facing configuration for the image-quality gate. Shared by both
30
43
  * config shapes that carry it — `ImageCaptureConfig` (what `ImageCaptureManager`
@@ -57,6 +70,14 @@ interface QualityFilterConfig {
57
70
  * motion gate's `maxWaitMs`). A sensible value is ~2× the capture interval.
58
71
  */
59
72
  maxWaitMs: number;
73
+ /**
74
+ * Which sharpness metric the blur check scores frames with. **Optional**
75
+ * for backward compatibility with configs persisted before the toggle
76
+ * existed: `undefined` means `'variance-of-laplacian'` (the original
77
+ * behavior) — resolve via {@link blurMetricScorer}, never by reading this
78
+ * field directly.
79
+ */
80
+ blurMetric?: BlurMetricId;
60
81
  }
61
82
  /**
62
83
  * Default image-quality configuration. **Disabled by default** (plan §10): the
@@ -108,6 +129,27 @@ declare function rgbaToGrayscale(rgba: Uint8Array | Uint8ClampedArray): Uint8Cla
108
129
  * an empty buffer.
109
130
  */
110
131
  declare function meanLuminance(rgba: Uint8Array | Uint8ClampedArray): number;
132
+ /**
133
+ * Frequency-domain focus measure: the fraction of non-DC spectral energy at
134
+ * normalized radial frequency ≥ `cutoff` (default 0.3), computed by FFT over
135
+ * the centered largest power-of-two crop (needs ≥ 8×8, else returns 0).
136
+ * In [0, 1]; higher ⇒ sharper. Unlike {@link sharpnessScore} it is invariant
137
+ * to brightness shift AND contrast scale (it is a ratio). Ported from the
138
+ * investigation benchmark (2026-07-12 toggle plan) where it won the
139
+ * "sharp vs degraded" boundary (AUC 0.838 vs 0.750).
140
+ *
141
+ * Defensive contract identical to {@link sharpnessScore}: non-integer or
142
+ * < 3×3 dims, or a buffer shorter than `width·height`, return 0.
143
+ */
144
+ declare function highFrequencyEnergyRatio(gray: Uint8Array | Uint8ClampedArray | readonly number[], width: number, height: number, cutoff?: number): number;
145
+ /**
146
+ * Resolve a {@link BlurMetricId} to its scoring function. `undefined` or an
147
+ * unknown id (e.g. from a persisted config written by a newer/older app
148
+ * version) resolves to {@link sharpnessScore} — the pre-toggle behavior.
149
+ * The (untestable) recorder worker calls this so the mapping stays here,
150
+ * where tests can pin it.
151
+ */
152
+ declare function blurMetricScorer(metric: BlurMetricId | undefined): (gray: Uint8Array | Uint8ClampedArray | readonly number[], width: number, height: number) => number;
111
153
  /** Reason a frame was rejected by the quality gate, or `null` when accepted. */
112
154
  type QualityRejectReason = 'black' | 'blurry';
113
155
  /** Outcome of evaluating one frame against the quality gate. */
@@ -155,4 +197,4 @@ declare class ImageQualityGate {
155
197
  reset(): void;
156
198
  }
157
199
  //#endregion
158
- export { QualityFilterConfig as a, meanLuminance as c, ImageQualityGate as i, rgbaToGrayscale as l, DEFAULT_SHARPNESS_HISTORY_SIZE as n, QualityRejectReason as o, DEFAULT_SHARPNESS_MIN_SAMPLES as r, QualityVerdict as s, DEFAULT_QUALITY_FILTER as t, sharpnessScore as u };
200
+ export { DEFAULT_SHARPNESS_MIN_SAMPLES as a, QualityRejectReason as c, highFrequencyEnergyRatio as d, meanLuminance as f, DEFAULT_SHARPNESS_HISTORY_SIZE as i, QualityVerdict as l, sharpnessScore as m, BlurMetricId as n, ImageQualityGate as o, rgbaToGrayscale as p, DEFAULT_QUALITY_FILTER as r, QualityFilterConfig as s, BLUR_METRIC_IDS as t, blurMetricScorer as u };
@@ -0,0 +1,64 @@
1
+ import { o as RgbaImage } from "./qr-frontend-BnLlVjKu.js";
2
+ //#region ../src/ar/camera-frame-source.d.ts
3
+ /** Tuning for the camera frame source. */
4
+ interface CameraFrameSourceConfig {
5
+ /**
6
+ * Minimum interval between captures in milliseconds. Default 125 ms (≈ 8 Hz),
7
+ * the plan §9 5–10 Hz detection target. The capture (and therefore the blit)
8
+ * fires at most once per `intervalMs`.
9
+ */
10
+ intervalMs: number;
11
+ }
12
+ /** Injected I/O for the camera frame source. */
13
+ interface CameraFrameSourceCallbacks {
14
+ /**
15
+ * Capture the current XR frame as top-left-origin RGBA, or `null` when no
16
+ * frame is available (no camera texture yet, GL failure). This is the GPU
17
+ * blit + readback; the source only invokes it at the throttled cadence so
18
+ * the cost is bounded. A `null` return does NOT consume the interval slot —
19
+ * the next frame retries immediately (a missing texture is transient).
20
+ */
21
+ capture: () => RgbaImage | null;
22
+ /** Receive a throttled, successfully-captured frame. */
23
+ onCapture: (image: RgbaImage) => void;
24
+ }
25
+ /**
26
+ * Throttled RGBA capturer. Construct with the injected `capture`/`onCapture`
27
+ * pair, `start()`, then call `onFrame(timestamp)` once per XR frame.
28
+ */
29
+ declare class CameraFrameSource {
30
+ private readonly callbacks;
31
+ private readonly config;
32
+ private running;
33
+ private captureCount;
34
+ private lastCaptureTime;
35
+ constructor(callbacks: CameraFrameSourceCallbacks, config?: Partial<CameraFrameSourceConfig>);
36
+ /** Begin throttling. Resets the cadence so the first tick captures. */
37
+ start(): void;
38
+ /** Stop capturing. `onFrame` becomes a no-op until `start()` is called again. */
39
+ stop(): void;
40
+ isRunning(): boolean;
41
+ /** Number of frames successfully captured + delivered since `start()`. */
42
+ getFrameCount(): number;
43
+ getConfig(): CameraFrameSourceConfig;
44
+ /**
45
+ * Apply partial config (e.g. the app's detection cadence). Invalid values
46
+ * are ignored defensively — `intervalMs` requires a finite positive number.
47
+ */
48
+ updateConfig(config: Partial<CameraFrameSourceConfig>): void;
49
+ /**
50
+ * Per-XR-frame tick. Captures + delivers a frame at most once per
51
+ * `intervalMs`; otherwise a cheap no-op so it is safe to call every frame.
52
+ *
53
+ * @param timestamp - monotonic frame time in ms (the XR `time` argument).
54
+ */
55
+ onFrame(timestamp: number): void;
56
+ /**
57
+ * Run the injected capture, guarded so a blit failure (e.g. GL context loss)
58
+ * can never throw out of the XR frame loop — it degrades to "no frame this
59
+ * tick", exactly like a missing texture.
60
+ */
61
+ private captureSafely;
62
+ }
63
+ //#endregion
64
+ export { CameraFrameSourceCallbacks as n, CameraFrameSourceConfig as r, CameraFrameSource as t };