gps-plus-slam-app-framework 1.4.0 → 1.8.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 (243) hide show
  1. package/dist/absolute-orientation-BAxc15J6.d.ts +54 -0
  2. package/dist/{accuracy-circles-Pi2YeCrM.d.ts → accuracy-circles-DkWBkF5g.d.ts} +16 -6
  3. package/dist/{app-selectors-CrOucL00.d.ts → app-selectors-JqydaUMN.d.ts} +1 -1
  4. package/dist/ar/bresenham3d.d.ts +1 -1
  5. package/dist/ar/camera-blit-capture.d.ts +1 -1
  6. package/dist/ar/capability-checker.d.ts +1 -1
  7. package/dist/ar/capture-failure-tracker.d.ts +1 -1
  8. package/dist/ar/chromium-camera-access-workaround.d.ts +1 -1
  9. package/dist/ar/depth-grid-lookup.d.ts +1 -1
  10. package/dist/ar/depth-occluder.d.ts +127 -0
  11. package/dist/ar/depth-occluder.js +299 -0
  12. package/dist/ar/depth-sampler.d.ts +2 -2
  13. package/dist/ar/depth-sampler.js +24 -4
  14. package/dist/ar/depth-unprojection.d.ts +1 -1
  15. package/dist/ar/depth-unprojection.js +52 -21
  16. package/dist/ar/enable-gps-ar.d.ts +1 -1
  17. package/dist/ar/enable-gps-ar.js +1 -1
  18. package/dist/ar/frame-loop.d.ts +1 -1
  19. package/dist/ar/frame-loop.js +12 -2
  20. package/dist/ar/image-capture.d.ts +2 -2
  21. package/dist/ar/image-capture.js +1 -154
  22. package/dist/ar/image-quality.d.ts +2 -0
  23. package/dist/ar/image-quality.js +169 -0
  24. package/dist/ar/index.d.ts +32 -30
  25. package/dist/ar/index.js +7 -5
  26. package/dist/ar/occlusion-mesh-worker.d.ts +58 -0
  27. package/dist/ar/occlusion-mesh-worker.js +129 -0
  28. package/dist/ar/occupancy-grid.d.ts +2 -2
  29. package/dist/ar/occupancy-grid.js +287 -31
  30. package/dist/ar/occupancy-mesher.d.ts +2 -0
  31. package/dist/ar/occupancy-mesher.js +638 -0
  32. package/dist/ar/planar-pnp.d.ts +1 -1
  33. package/dist/ar/qr-debug-view.d.ts +1 -1
  34. package/dist/ar/qr-derived-pose.d.ts +1 -1
  35. package/dist/ar/qr-detection-controller.d.ts +1 -1
  36. package/dist/ar/qr-frontend.d.ts +1 -1
  37. package/dist/ar/qr-pose.d.ts +1 -1
  38. package/dist/ar/qr-size-depth-context.d.ts +2 -2
  39. package/dist/ar/qr-size-measurer.d.ts +1 -1
  40. package/dist/ar/replay-scene.d.ts +1 -1
  41. package/dist/ar/replay-scene.js +1 -1
  42. package/dist/ar/scene-node-names.d.ts +1 -1
  43. package/dist/ar/webxr-nue-basis.d.ts +1 -1
  44. package/dist/ar/webxr-session.d.ts +4 -4
  45. package/dist/ar/webxr-session.js +2 -2
  46. package/dist/ar/xr-camera-texture.d.ts +1 -1
  47. package/dist/ar/xr-error-handler.d.ts +1 -1
  48. package/dist/ar/xr-frame-loop.d.ts +1 -1
  49. package/dist/ar/xr-frame-loop.js +12 -2
  50. package/dist/{ar-Dc72Ksiu.js → ar-BqCudtqE.js} +4 -3
  51. package/dist/{ar-world-group-alignment-DDLkgNf_.d.ts → ar-world-group-alignment-BlvGcIAk.d.ts} +1 -1
  52. package/dist/capture-motion-gate-BGoAMkmf.d.ts +24 -0
  53. package/dist/capture-motion-gate-_NdTSwKi.js +106 -0
  54. package/dist/cell-key-DIB4rOTV.js +51 -0
  55. package/dist/core/index.d.ts +2 -2
  56. package/dist/core/index.js +2 -2
  57. package/dist/{create-slam-app-store-Ce2FMKCp.d.ts → create-slam-app-store-D3nzh9Wb.d.ts} +50 -40
  58. package/dist/create-slam-app-store-DXiAnJwR.js +156 -0
  59. package/dist/{depth-grid-lookup-vMDrGTk_.d.ts → depth-grid-lookup-D5atpNZ3.d.ts} +1 -1
  60. package/dist/{depth-sampler-DwfPYzS7.d.ts → depth-sampler-CwObAwEA.d.ts} +33 -1
  61. package/dist/{depth-unprojection-CK3b9htH.d.ts → depth-unprojection-DRdBU90S.d.ts} +1 -1
  62. package/dist/{enable-gps-ar-CjZ1nEdu.d.ts → enable-gps-ar-DvGzBOrp.d.ts} +4 -4
  63. package/dist/{frame-conversions-D_Af8Dt3.d.ts → frame-conversions-C4bnNOEY.d.ts} +1 -1
  64. package/dist/{fused-path-C0FHe67t.d.ts → fused-path-C5pp0PJU.d.ts} +1 -1
  65. package/dist/geo/h3-proximity.d.ts +1 -1
  66. package/dist/geo/index.d.ts +1 -1
  67. package/dist/geodesic-angle-BTldfFgs.js +39 -0
  68. package/dist/{gps-anchor-C6I9NDHA.d.ts → gps-anchor-BjECcYnD.d.ts} +1 -1
  69. package/dist/{gps-ar-pose-sampler-DaHg2aPZ.d.ts → gps-ar-pose-sampler-DEGNk2CI.d.ts} +1 -1
  70. package/dist/{gps-event-coordinator-C7hwHyLA.d.ts → gps-event-coordinator-CHtIkhb7.d.ts} +21 -11
  71. package/dist/{image-capture-C2Feywet.d.ts → image-capture-Bp6Pd4Md.d.ts} +103 -3
  72. package/dist/image-capture-DVcuqMtX.js +374 -0
  73. package/dist/image-quality-BMx2ko9-.d.ts +158 -0
  74. package/dist/index-D4vrgV4b.d.ts +2 -0
  75. package/dist/index-D74JTX4I.d.ts +22 -0
  76. package/dist/{index-m_LneUSi.d.ts → index-DlsOo2IB.d.ts} +1 -1
  77. package/dist/{index-BvLo2poy.d.ts → index-cCQWuYqy.d.ts} +3 -3
  78. package/dist/index.d.ts +82 -77
  79. package/dist/index.js +15 -10
  80. package/dist/{leaflet-map-overlay-bnb2U1NQ.d.ts → leaflet-map-overlay-BOZFW5kT.d.ts} +64 -10
  81. package/dist/leaflet-map-overlay-CBWPvaX9.js +452 -0
  82. package/dist/lerp-utils-Qs8OhumS.d.ts +42 -0
  83. package/dist/map-data-D7rpMC6f.js +120 -0
  84. package/dist/{map-data-DdjPiSav.d.ts → map-data-PNfGKGWx.d.ts} +22 -2
  85. package/dist/{map-overlay-draw-CPVdAsFq.d.ts → map-overlay-draw-DiroaJed.d.ts} +1 -1
  86. package/dist/{null-storage-backend-CuSdYFsM.d.ts → null-storage-backend-B1-jlpin.d.ts} +2 -2
  87. package/dist/occlusion-mesh-b28lRJ6S.d.ts +194 -0
  88. package/dist/occupancy-grid-BV7RhB7I.d.ts +194 -0
  89. package/dist/occupancy-mesher-C2ecWhNp.d.ts +100 -0
  90. package/dist/{opfs-storage-DMtlt57S.d.ts → opfs-storage-CTkxvxN4.d.ts} +5 -0
  91. package/dist/{opfs-storage-backend-CeQAb0SD.d.ts → opfs-storage-backend-D6Z03fML.d.ts} +2 -2
  92. package/dist/{persistence-middleware-5eearhSV.d.ts → persistence-middleware-CG-t08X4.d.ts} +1 -1
  93. package/dist/{planar-pnp-cjthe7Be.d.ts → planar-pnp-D7bc_rLX.d.ts} +1 -1
  94. package/dist/{qr-debug-view-B8gTzjMm.d.ts → qr-debug-view-BJooqbiP.d.ts} +1 -1
  95. package/dist/{qr-derived-pose-DinKE600.d.ts → qr-derived-pose-BwNWn8oV.d.ts} +2 -2
  96. package/dist/{qr-detected-slice-Cpv-dg82.d.ts → qr-detected-slice-TzVb8bij.d.ts} +4 -4
  97. package/dist/{qr-detection-controller-Cd2Ih4cC.d.ts → qr-detection-controller-Bo4XfQTP.d.ts} +3 -3
  98. package/dist/{qr-frontend-DufZp2xS.d.ts → qr-frontend-BPURlh3S.d.ts} +1 -1
  99. package/dist/{qr-pose-aggregation-CFlmLm6w.d.ts → qr-pose-aggregation-CypnmjA-.d.ts} +1 -1
  100. package/dist/{qr-pose-aggregation-DXR9STHs.js → qr-pose-aggregation-DBiaLW0O.js} +1 -10
  101. package/dist/{qr-size-depth-context-onu36E9s.d.ts → qr-size-depth-context-apAOmbrZ.d.ts} +2 -2
  102. package/dist/{qr-size-measurer-D7739ZpB.d.ts → qr-size-measurer-DxiMqRUw.d.ts} +3 -3
  103. package/dist/recording-options-vASCFzc5.d.ts +667 -0
  104. package/dist/{recording-replayer-CUEK82tM.d.ts → recording-replayer-D0V9WkmY.d.ts} +2 -2
  105. package/dist/{recording-slice-B-uCgGoh.d.ts → recording-slice-DTUtSVgd.d.ts} +2 -2
  106. package/dist/{replay-engine-BSVd7Zzb.d.ts → replay-engine-xdrUgWJi.d.ts} +1 -1
  107. package/dist/{replay-scene-CPt56pps.d.ts → replay-scene-zJ8SFDjE.d.ts} +3 -3
  108. package/dist/sensors/absolute-orientation.d.ts +2 -0
  109. package/dist/sensors/absolute-orientation.js +162 -0
  110. package/dist/sensors/gps-error-handler.d.ts +1 -1
  111. package/dist/sensors/gps.d.ts +1 -1
  112. package/dist/sensors/index.d.ts +5 -4
  113. package/dist/sensors/index.js +2 -1
  114. package/dist/sensors/permission-checker.d.ts +1 -1
  115. package/dist/state/app-selectors.d.ts +1 -1
  116. package/dist/state/combined-root-state.d.ts +1 -1
  117. package/dist/state/create-slam-app-store.d.ts +1 -1
  118. package/dist/state/create-slam-app-store.js +1 -74
  119. package/dist/state/gps-ar-pose-sampler.d.ts +3 -3
  120. package/dist/state/gps-event-coordinator.d.ts +2 -2
  121. package/dist/state/gps-event-coordinator.js +27 -17
  122. package/dist/state/index.d.ts +20 -20
  123. package/dist/state/index.js +4 -4
  124. package/dist/state/persistence-middleware.d.ts +1 -1
  125. package/dist/state/persistence-middleware.js +30 -19
  126. package/dist/state/qr-detected-slice.d.ts +3 -3
  127. package/dist/state/qr-detected-slice.js +1 -1
  128. package/dist/state/recording-options.d.ts +2 -2
  129. package/dist/state/recording-options.js +286 -25
  130. package/dist/state/recording-replayer.d.ts +2 -2
  131. package/dist/state/recording-replayer.js +1 -1
  132. package/dist/state/recording-slice.d.ts +1 -1
  133. package/dist/state/replay-engine.d.ts +1 -1
  134. package/dist/state/store-subscribers.d.ts +2 -2
  135. package/dist/state/store-subscribers.js +2 -1
  136. package/dist/state/subscribe-to-selector.d.ts +1 -1
  137. package/dist/state/tracking-quality.d.ts +2 -2
  138. package/dist/state/tracking-quality.js +49 -128
  139. package/dist/state/tracking-slice.d.ts +1 -1
  140. package/dist/{state-IEw0ZsBu.js → state-BeKvn4B-.js} +1 -1
  141. package/dist/storage/file-system-utils.d.ts +1 -1
  142. package/dist/storage/index.d.ts +8 -8
  143. package/dist/storage/null-storage-backend.d.ts +1 -1
  144. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  145. package/dist/storage/opfs-storage.d.ts +1 -1
  146. package/dist/storage/opfs-storage.js +25 -1
  147. package/dist/storage/storage-backend.d.ts +1 -1
  148. package/dist/storage/zip-coverage-embed.d.ts +1 -1
  149. package/dist/storage/zip-export.d.ts +1 -1
  150. package/dist/storage/zip-reader.d.ts +1 -1
  151. package/dist/{storage-backend-CTJHNdMp.d.ts → storage-backend-sEtmM4yW.d.ts} +1 -1
  152. package/dist/{store-subscribers-BZP81hjh.d.ts → store-subscribers-DScA7tdT.d.ts} +2 -2
  153. package/dist/{subscribe-to-selector-Bp3sLx8L.d.ts → subscribe-to-selector-B9ylM5Oh.d.ts} +1 -1
  154. package/dist/test-utils/browser-mocks.d.ts +1 -1
  155. package/dist/test-utils/zip-round-trip-helpers.d.ts +1 -1
  156. package/dist/{tracking-slice-DJZ9qeGg.d.ts → tracking-slice-DMkHlbny.d.ts} +1 -1
  157. package/dist/types/ar-types.d.ts +1 -1
  158. package/dist/types/geo-types.d.ts +1 -1
  159. package/dist/types/index.d.ts +2 -2
  160. package/dist/utils/concurrency.d.ts +1 -1
  161. package/dist/utils/failure-tracker.d.ts +1 -1
  162. package/dist/utils/format-file-size.d.ts +1 -1
  163. package/dist/utils/fused-path.d.ts +1 -1
  164. package/dist/utils/index.d.ts +8 -7
  165. package/dist/utils/index.js +2 -1
  166. package/dist/utils/list-formatter.d.ts +1 -1
  167. package/dist/utils/logger.d.ts +1 -1
  168. package/dist/visualization/accuracy-circles.d.ts +1 -1
  169. package/dist/visualization/accuracy-circles.js +17 -8
  170. package/dist/visualization/alignment-lerper.d.ts +1 -1
  171. package/dist/visualization/ar-world-group-alignment.d.ts +1 -1
  172. package/dist/visualization/ar-world-group-alignment.js +1 -1
  173. package/dist/visualization/camera-follower.d.ts +1 -1
  174. package/dist/visualization/css3d-renderer-manager.d.ts +1 -1
  175. package/dist/visualization/frame-conversions.d.ts +1 -1
  176. package/dist/visualization/frustum-visibility.d.ts +1 -1
  177. package/dist/visualization/gps-anchor.d.ts +1 -1
  178. package/dist/visualization/gps-compass-cubes.d.ts +1 -1
  179. package/dist/visualization/gps-event-markers.d.ts +1 -1
  180. package/dist/visualization/gps-event-markers.js +1 -1
  181. package/dist/visualization/hit-test-reticle.d.ts +1 -1
  182. package/dist/visualization/index.d.ts +20 -19
  183. package/dist/visualization/index.js +4 -3
  184. package/dist/visualization/leaflet-map-overlay.d.ts +1 -1
  185. package/dist/visualization/leaflet-map-overlay.js +1 -282
  186. package/dist/visualization/lerp-utils.d.ts +2 -2
  187. package/dist/visualization/lerp-utils.js +27 -3
  188. package/dist/visualization/map-data.d.ts +1 -1
  189. package/dist/visualization/map-data.js +1 -32
  190. package/dist/visualization/map-overlay-draw.d.ts +1 -1
  191. package/dist/visualization/map-overlay-draw.js +24 -2
  192. package/dist/visualization/map-overlay.d.ts +1 -1
  193. package/dist/visualization/occluder-mesh-driver.d.ts +130 -0
  194. package/dist/visualization/occluder-mesh-driver.js +219 -0
  195. package/dist/visualization/occlusion-mesh.d.ts +2 -0
  196. package/dist/visualization/occlusion-mesh.js +437 -0
  197. package/dist/visualization/three-dispose.d.ts +1 -1
  198. package/dist/visualization/vis-colors.d.ts +1 -1
  199. package/dist/{webxr-session-CJF9Nijp.js → webxr-session-BCP2XK7k.js} +110 -14
  200. package/dist/{webxr-session-COsOjJwn.d.ts → webxr-session-cRG2SYAQ.d.ts} +83 -10
  201. package/package.json +4 -4
  202. package/dist/index-eaI1Z1KR.d.ts +0 -2
  203. package/dist/lerp-utils-kLxMJ2Xj.d.ts +0 -20
  204. package/dist/occupancy-grid-Bvi2Gw1U.d.ts +0 -82
  205. package/dist/recording-options-D93kksJU.d.ts +0 -369
  206. /package/dist/{alignment-lerper-BUTsQ2yu.d.ts → alignment-lerper-gD70k7Fq.d.ts} +0 -0
  207. /package/dist/{ar-types-BckI1E-O.d.ts → ar-types-Cc5yvBwn.d.ts} +0 -0
  208. /package/dist/{bresenham3d-ByjcmEgM.d.ts → bresenham3d-DGc4nIb-.d.ts} +0 -0
  209. /package/dist/{camera-blit-capture-CqWe1G7s.d.ts → camera-blit-capture-BimSdyih.d.ts} +0 -0
  210. /package/dist/{camera-follower-BTb2Yp12.d.ts → camera-follower-DfBm2J5i.d.ts} +0 -0
  211. /package/dist/{capability-checker-CXqoJYtb.d.ts → capability-checker-BTTpygvZ.d.ts} +0 -0
  212. /package/dist/{capture-failure-tracker-BL5SoG2a.d.ts → capture-failure-tracker-_BVfhpxv.d.ts} +0 -0
  213. /package/dist/{chromium-camera-access-workaround-BNK189P0.d.ts → chromium-camera-access-workaround-C6yJLXz9.d.ts} +0 -0
  214. /package/dist/{concurrency-DqAlKX4j.d.ts → concurrency-DPeGBH0X.d.ts} +0 -0
  215. /package/dist/{css3d-renderer-manager-m-ab19vp.d.ts → css3d-renderer-manager-CPpVtvgs.d.ts} +0 -0
  216. /package/dist/{failure-tracker-Cnc_xWUw.d.ts → failure-tracker-CeKf5HIc.d.ts} +0 -0
  217. /package/dist/{file-system-utils-Bs7lpeVP.d.ts → file-system-utils-DueXHxo9.d.ts} +0 -0
  218. /package/dist/{format-file-size-BFUWvir1.d.ts → format-file-size-DxN-EBLc.d.ts} +0 -0
  219. /package/dist/{frame-loop-BEO9_q3k.d.ts → frame-loop-7GBMBu68.d.ts} +0 -0
  220. /package/dist/{frustum-visibility-D_RGmH98.d.ts → frustum-visibility-CokkgS_i.d.ts} +0 -0
  221. /package/dist/{geo-types-DqiBzPO9.d.ts → geo-types-DrGVu8nS.d.ts} +0 -0
  222. /package/dist/{gps-C5inWeNV.d.ts → gps-CDKDQokE.d.ts} +0 -0
  223. /package/dist/{gps-compass-cubes-BExxrWJ-.d.ts → gps-compass-cubes-1mooS3BS.d.ts} +0 -0
  224. /package/dist/{gps-error-handler-C2bS69oJ.d.ts → gps-error-handler-C34GQuTu.d.ts} +0 -0
  225. /package/dist/{gps-event-markers-Dd0G2bD0.d.ts → gps-event-markers-Di2nBzx-.d.ts} +0 -0
  226. /package/dist/{h3-proximity-B57C6rYL.d.ts → h3-proximity-D0GTHQmr.d.ts} +0 -0
  227. /package/dist/{hit-test-reticle-Dqak9hiR.d.ts → hit-test-reticle-CaQbrhbk.d.ts} +0 -0
  228. /package/dist/{list-formatter-ct8txwvR.d.ts → list-formatter-DLFDnS70.d.ts} +0 -0
  229. /package/dist/{logger-CzQrCe6C.d.ts → logger-CqTd5Kpk.d.ts} +0 -0
  230. /package/dist/{map-overlay-Dci4yvm3.d.ts → map-overlay-BCQgvIgU.d.ts} +0 -0
  231. /package/dist/{permission-checker-CtPtPQRq.d.ts → permission-checker-B-VtjnBA.d.ts} +0 -0
  232. /package/dist/{qr-pose-Bt2reSw7.d.ts → qr-pose-y3vaEd6x.d.ts} +0 -0
  233. /package/dist/{scene-node-names-CdNeQjOE.d.ts → scene-node-names-CGb-ylBd.d.ts} +0 -0
  234. /package/dist/{session-disposers-D8wnO-uW.js → session-disposers-BPrMplIC.js} +0 -0
  235. /package/dist/{three-dispose-BCZkSJp2.d.ts → three-dispose-BMOAmPhb.d.ts} +0 -0
  236. /package/dist/{vis-colors-BZsSLI4i.d.ts → vis-colors-C7HI0u9_.d.ts} +0 -0
  237. /package/dist/{webxr-nue-basis-CW1wsbm6.d.ts → webxr-nue-basis-CaCnYxuq.d.ts} +0 -0
  238. /package/dist/{xr-camera-texture-BmrP7iNZ.d.ts → xr-camera-texture-q0eIDSRg.d.ts} +0 -0
  239. /package/dist/{xr-error-handler-BEjRgZjt.d.ts → xr-error-handler-uVGDu9IX.d.ts} +0 -0
  240. /package/dist/{xr-frame-loop-K8ebdjLw.d.ts → xr-frame-loop-DX3JPpAU.d.ts} +0 -0
  241. /package/dist/{zip-coverage-embed-tFohI2J4.d.ts → zip-coverage-embed-ncVbaZAz.d.ts} +0 -0
  242. /package/dist/{zip-export-DDWXInTR.d.ts → zip-export-CtiUnAlJ.d.ts} +0 -0
  243. /package/dist/{zip-reader-Q2ue6zlC.d.ts → zip-reader-CvruaGvD.d.ts} +0 -0
@@ -0,0 +1,667 @@
1
+ import { t as MotionFilterConfig } from "./capture-motion-gate-BGoAMkmf.js";
2
+ import { a as QualityFilterConfig } from "./image-quality-BMx2ko9-.js";
3
+
4
+ //#region ../src/state/recording-options.d.ts
5
+ /**
6
+ * Input type for validateRecordingOptions allowing partial nested objects.
7
+ * This allows passing incomplete objects that will be merged with defaults.
8
+ */
9
+ interface RecordingOptionsInput {
10
+ depth?: Partial<DepthCaptureOptions>;
11
+ images?: Partial<ImageCaptureOptions>;
12
+ arCrashIsolation?: Partial<ArCrashIsolationOptions>;
13
+ occupancy?: Partial<OccupancyOptions>;
14
+ frameTileDisplay?: Partial<FrameTileDisplayOptions>;
15
+ visualization?: Partial<VisualizationOptions>;
16
+ qr?: Partial<QrCaptureOptions>;
17
+ compassDebug?: Partial<CompassDebugOptions>;
18
+ }
19
+ /**
20
+ * Toggles for the library's Phase-4 compass alignment features (closed/internal
21
+ * `AlignmentConfig` flags exposed via narrow boolean actions). They change how
22
+ * the LIVE alignment is computed, so they sit with the other capture groups.
23
+ * **Stage 0 (`coldStartOverride`) defaults ON** (a field-validated production
24
+ * feature); Stage C + the WebXR-consistency gate stay experimental (default
25
+ * OFF) until the §6a field-data matrix is in.
26
+ *
27
+ * On-device caveat: the resulting `gpsData` opt-in actions persist into the
28
+ * recording, so the DEFAULT `replayAll` re-enables them. This does NOT modify the
29
+ * raw recorded stream (`rawAbsoluteOrientation`, GPS, odometry) — only the
30
+ * *derived* alignment — so an investigation that re-solves from the raw
31
+ * observations under a chosen `AlignmentConfig` (`recomputeAlignment`) is
32
+ * unaffected by the capture-time flag state. Turning the flags off during capture
33
+ * only matters if you want the LIVE app to behave as the GPS-only baseline; it is
34
+ * not required for clean §6a analysis data. See
35
+ * `GpsPlusSlamJs_Docs/docs/2026-06-26-stage0-field-collection-and-enablement.md`
36
+ * (2026-07-01 update).
37
+ */
38
+ interface CompassDebugOptions {
39
+ /** Stage 0 — cold-start compass yaw override (`setColdStartOverrideEnabled`). Default ON. */
40
+ coldStartOverride: boolean;
41
+ /** Stage C — trust-gated compass rotation prior (`setCompassRotationPriorEnabled`). */
42
+ rotationPrior: boolean;
43
+ /** GPS-free compass↔WebXR consistency gate (`setCompassWebXRConsistencyEnabled`). */
44
+ webXRConsistency: boolean;
45
+ }
46
+ /**
47
+ * Diagnostic flags for isolating pre-recording AR startup crashes.
48
+ * These gates affect XR session negotiation and frame-loop behavior,
49
+ * independently of recording-time image/depth capture.
50
+ */
51
+ interface ArCrashIsolationOptions {
52
+ enableDomOverlay: boolean;
53
+ enableCameraAccess: boolean;
54
+ enableDepthSensingFeature: boolean;
55
+ enableCss3dRenderer: boolean;
56
+ enableCameraTextureAcquisition: boolean;
57
+ /**
58
+ * Apply the Chromium WebXR camera-access tab-crash workaround at app
59
+ * bootstrap. The workaround always deletes
60
+ * `XRWebGLBinding.prototype.createProjectionLayer` /
61
+ * `XRRenderState.prototype.layers` (forcing `XRWebGLLayer`) — required on
62
+ * every affected Chrome build observed on-device, including Chrome 150 — and
63
+ * additionally persists the `baseLayer` across
64
+ * `XRSession.prototype.updateRenderState` only for Chrome builds inside the
65
+ * affected window (148.0.7778.12 up to 149.0.7821).
66
+ *
67
+ * Default `true`. Opt-out is offered because forcing `XRWebGLLayer` may break
68
+ * WebXR on unaffected (e.g. Quest) devices.
69
+ *
70
+ * @see GpsPlusSlamJs_AppFramework/src/ar/chromium-camera-access-workaround.ts
71
+ * @see https://github.com/mrdoob/three.js/issues/33404
72
+ */
73
+ applyChromiumProjectionLayerWorkaround: boolean;
74
+ }
75
+ /**
76
+ * Configuration for depth sampling during recording.
77
+ */
78
+ interface DepthCaptureOptions {
79
+ /** Whether to capture depth samples. Default: true */
80
+ enabled: boolean;
81
+ /** Interval between samples in milliseconds. Default: 500 (FAST-reconstruction tuning, 2026-07-01). */
82
+ intervalMs: number;
83
+ /**
84
+ * Grid size (N×N points per sample). Default: 32 (FAST-reconstruction
85
+ * tuning, 2026-07-01) — dense enough to populate the AR-space occupancy
86
+ * grid (2026-06-11 port plan §1).
87
+ */
88
+ gridSize: number;
89
+ /**
90
+ * Whether to enrich each depth point with the camera color at its view
91
+ * coordinates (RGB voxel coloring, occupancy-grid port plan Iter 8).
92
+ * Costs one small GPU blit+readback per sample (~1 Hz); when off, the
93
+ * occupancy cubes keep the height-based coloring. Default: true.
94
+ */
95
+ rgb: boolean;
96
+ }
97
+ /**
98
+ * Configuration for image capture during recording.
99
+ */
100
+ interface ImageCaptureOptions {
101
+ /** Whether to capture images. Default: true */
102
+ enabled: boolean;
103
+ /** Interval between captures in milliseconds. Default: 2000 */
104
+ intervalMs: number;
105
+ /** JPEG quality (0.0 - 1.0). Default: 0.7 */
106
+ quality: number;
107
+ /** Resolution divisor: 1 = full native resolution, 2 = half, 4 = quarter. Default: 1 */
108
+ resolutionDivisor: number;
109
+ /**
110
+ * Motion gate — skip motion-blurred frames by deferring a due capture until
111
+ * device motion settles. Mirrors `ImageCaptureConfig.motionFilter` (the type
112
+ * the capture manager consumes); the recorder destructures `images` and flows
113
+ * the rest, including this group, through the capture seam. Default: enabled.
114
+ * See `ar/capture-motion-gate.ts` and
115
+ * `GpsPlusSlamJs_Docs/docs/2026-06-23-blurry-frame-motion-gating-plan.md`.
116
+ */
117
+ motionFilter: MotionFilterConfig;
118
+ /**
119
+ * Image-quality gate — drop a blurry/black frame (judged off-thread) and retry
120
+ * the next acceptable frame. Mirrors `ImageCaptureConfig.qualityFilter`; flows
121
+ * through the same capture seam as `motionFilter`. **Default: disabled**
122
+ * pending field tuning of the relative blur threshold (a mis-tuned gate
123
+ * silently dropping good frames is worse than the motion gate's default-on).
124
+ * See `ar/image-quality.ts` and
125
+ * `GpsPlusSlamJs_Docs/docs/2026-06-24-image-quality-gate-plan.md`.
126
+ */
127
+ qualityFilter: QualityFilterConfig;
128
+ }
129
+ /**
130
+ * Configuration for the derived AR-space occupancy grid (the voxelization of
131
+ * the depth samples, port plan 2026-06-11). These settings do NOT change what
132
+ * is recorded — they govern the grid derived from the recorded depth points,
133
+ * so they also apply when replaying an existing recording, letting the same
134
+ * session be re-quantized at a different resolution.
135
+ */
136
+ /**
137
+ * Mesher strategy for the **persistent occluder** mesh, exposed as a recorder
138
+ * setting (2026-06-30 occluder-tuning, F2/F2b) so the two surface-hugging
139
+ * approaches can be A/B-tested on-device against the blocky baseline:
140
+ * - `'greedy'` — blocky greedy cubes (the existing default; fewest triangles).
141
+ * - `'corner-fit'` — cubes with corners pulled to the measured centroids
142
+ * (surface-hugging **and** watertight).
143
+ * - `'smooth'` — surface nets: smoothest, hugs the measured surface, but an open
144
+ * sheet over thin features.
145
+ *
146
+ * Maps directly onto `meshOccupiedCells` / `OcclusionMesh` `MeshMode` (a subset).
147
+ * `'per-face'` is intentionally not offered (same shape as `'greedy'`, more
148
+ * triangles — no on-device value).
149
+ */
150
+ declare const OCCLUDER_MESH_MODES: readonly ["greedy", "corner-fit", "smooth"];
151
+ type OccluderMeshMode = (typeof OCCLUDER_MESH_MODES)[number];
152
+ /**
153
+ * Debug-visualization style for the **persistent occluder** mesh (2026-07-02
154
+ * debug-viz-styles plan) — which visible debug skin(s) `OcclusionMesh` renders
155
+ * on top of the invisible depth-only occluder:
156
+ * - `'off'` — no debug rendering (the shipped default; occlusion is invisible).
157
+ * - `'matcap'` — the original shiny semi-transparent cyan skin.
158
+ * - `'depth-shaded'` — matcap + camera-distance fade + white fresnel rim, so
159
+ * overlapping near/far surfaces read as separate shells.
160
+ * - `'wireframe'` — the raw triangulation as GL lines (mesh-structure
161
+ * inspection: triangle density, mesher seams, degenerate spots).
162
+ * - `'depth-shaded-wireframe'` — both of the above composed.
163
+ *
164
+ * Values array module-private (validation only; the settings `<select>`
165
+ * options are hardcoded in the recorder's `index.html`), type exported —
166
+ * mirroring `OCCLUDER_MESH_MODES` / {@link OccluderMeshMode}.
167
+ */
168
+ declare const OCCLUDER_DEBUG_STYLES: readonly ["off", "matcap", "depth-shaded", "wireframe", "depth-shaded-wireframe"];
169
+ type OccluderDebugStyle = (typeof OCCLUDER_DEBUG_STYLES)[number];
170
+ interface OccupancyOptions {
171
+ /**
172
+ * Voxel edge length in metres. Drives the occupancy-grid quantization, the
173
+ * debug cubes, and the COLMAP `points3D` density. Default 0.15 (15 cm, Unity
174
+ * parity). Smaller = finer detail but cell count scales as 1/cellSize³, so the
175
+ * range is deliberately clamped (see `OCCUPANCY_CONSTRAINTS`). Read once when
176
+ * the grid is constructed (Enter-AR / replay load), so a change takes effect
177
+ * on the next session rather than mid-session.
178
+ */
179
+ cellSizeM: number;
180
+ /**
181
+ * Minimum observation count for a voxel to be trusted as occupied (the
182
+ * grid's `getOccupiedCells(minObservations)` floor, promoted to a user
183
+ * setting). A cell is marked occupied the instant one noisy depth point
184
+ * lands in it; raising this filters single-frame depth noise — in
185
+ * particular the **behind-surface** phantoms (e.g. below the floor) that
186
+ * free-space carving can never clear because no ray passes through occluded
187
+ * space. Default 3 (1 = unfiltered/legacy). Higher = less noise but
188
+ * briefly-glimpsed real surfaces may be dropped, so it is exposed for
189
+ * on-device tuning. Read once when the visualizer is constructed (Enter-AR
190
+ * / replay load). See
191
+ * `GpsPlusSlamJs_Docs/docs/2026-06-22-occupancy-grid-behind-surface-noise-plan.md`.
192
+ */
193
+ minConfidence: number;
194
+ /**
195
+ * Render a **persistent depth-only occlusion mesh** of the occupancy grid:
196
+ * the grid's occupied cells are meshed (`meshOccupiedCells`) and drawn
197
+ * invisible-but-depth-writing under `arWorldGroup`, so real geometry the
198
+ * camera saw earlier hides virtual objects placed behind it — including
199
+ * out-of-view surfaces a live depth occluder cannot remember. Default
200
+ * **true** (since 2026-07-01): the Web-Worker mesh offload removed the
201
+ * per-refresh render stall that was the reason to keep it opt-in, so the
202
+ * remembered occluder ships on by the default `'smooth'` mesher. Read once when
203
+ * the mesh is wired (Enter-AR / replay load), like the other occupancy knobs.
204
+ * See `GpsPlusSlamJs_Docs/docs/2026-06-13-occupancy-mesh-options-plan.md` and
205
+ * `GpsPlusSlamJs_Docs/docs/2026-07-01-occluder-worker-and-chunked-remesh-plan.md`.
206
+ *
207
+ * **Migration:** this field replaces the former `occlusionMeshEnabled`
208
+ * boolean — `validateOccupancyOptions` maps a persisted
209
+ * `occlusionMeshEnabled === true` onto `persistentOcclusion` (see that
210
+ * function and `2026-06-29-occupancy-mesh-followups.md`).
211
+ */
212
+ persistentOcclusion: boolean;
213
+ /**
214
+ * Enable the **live CPU-depth occluder** — a per-frame depth occluder that
215
+ * hides virtual content behind the real surface the camera sees *right now*,
216
+ * sharp and registration-free (no out-of-view memory). It composes with
217
+ * {@link persistentOcclusion}: both can be on (the live occluder wins where
218
+ * this frame has depth, the persistent mesh fills out-of-view / depth holes —
219
+ * `2026-06-14-webxr-depth-occlusion-plan.md` §5). Requires the
220
+ * `requestDepthOcclusion` session feature so `cpu-optimized` depth is
221
+ * negotiated even without depth recording. **Live-AR only** — replay has no
222
+ * live depth stream, so this flag is a no-op there (persistent still applies).
223
+ * Default **false**: the live occluder's on-device occlusion quality is still
224
+ * device-gated/unverified. Read once when the AR session is wired (Enter-AR).
225
+ */
226
+ liveOcclusion: boolean;
227
+ /**
228
+ * Which **visible debug skin(s)** render the persistent occluder mesh (see
229
+ * {@link OccluderDebugStyle}) so its shape/structure can be judged on-device.
230
+ * All styles are additive overlays — the invisible depth-only mesh keeps
231
+ * writing depth unchanged, so occlusion is identical in every style. Only has
232
+ * a visible effect when {@link persistentOcclusion} is on (it is that
233
+ * occluder's mesh); any other value is a harmless no-op. Default **`'off'`**.
234
+ * Read once when the mesh is wired (Enter-AR / replay load), like the other
235
+ * occupancy knobs. See
236
+ * `GpsPlusSlamJs_Docs/docs/2026-07-02-occluder-debug-viz-styles-plan.md` and
237
+ * `GpsPlusSlamJs_Docs/docs/2026-06-29-occlusion-debug-viz-and-live-occluder-user-feedback.md`.
238
+ *
239
+ * **Migration:** this field replaces the former `occluderDebugViz` boolean —
240
+ * `validateOccupancyOptions` maps a persisted `occluderDebugViz: true` onto
241
+ * `'matcap'` (the skin the boolean used to enable) when this field is absent,
242
+ * mirroring the `occlusionMeshEnabled` → {@link persistentOcclusion}
243
+ * migration.
244
+ */
245
+ occluderDebugStyle: OccluderDebugStyle;
246
+ /**
247
+ * Which mesher builds the **persistent occluder** mesh (see
248
+ * {@link OccluderMeshMode}). Default `'smooth'` (since 2026-07-01) — Naive
249
+ * Surface Nets, the smoothest and lightest mesh. Switch to `'greedy'` (blocky
250
+ * cubes, watertight) or `'corner-fit'` (surface-hugging + watertight) if the
251
+ * smooth mesh's open concave seams leak occlusion in practice (combine with
252
+ * {@link occluderDebugStyle} to actually *see* the mesh shape). Only has an
253
+ * effect when {@link persistentOcclusion} is on. Read once when the mesh is
254
+ * wired (Enter-AR / replay load), like the other occupancy knobs. See
255
+ * `GpsPlusSlamJs_Docs/docs/2026-06-30-occluder-tuning-followups.md`.
256
+ */
257
+ occluderMeshMode: OccluderMeshMode;
258
+ /**
259
+ * Camera-local window for the **persistent occluder** snapshot (Step 2 of
260
+ * the 2026-07-03 long-session fps plan): each re-mesh reads only the
261
+ * occupied cells within this many meters of the camera
262
+ * (`OccupancyGrid.getOccupiedCellsWithinFlat`), so snapshot/pack/mesh cost
263
+ * is bounded by the neighbourhood instead of the whole session. Default
264
+ * **25 m** — a 15 cm voxel at 25 m subtends ~0.3°, so occlusion errors
265
+ * beyond that are imperceptible. `0` = unbounded (the pre-Step-2
266
+ * behaviour, the safe fallback). The grid forgets nothing: walking back
267
+ * re-meshes far geometry from memory — exactly the persistent-grid intent.
268
+ * Only has an effect when {@link persistentOcclusion} is on. Read once at
269
+ * Enter-AR / replay load like the other occupancy knobs.
270
+ */
271
+ occluderRadiusM: number;
272
+ }
273
+ /**
274
+ * Configuration for how captured frame tiles are DISPLAYED in AR (D7-resolution,
275
+ * 2026-06-16 RecorderApp user feedback / Q3). This is **distinct from** the
276
+ * capture setting `images.resolutionDivisor`: capture quality (the JPEG written
277
+ * to the recording) is unchanged — this only downscales the in-AR/replay display
278
+ * texture built from each captured frame, cutting per-tile GPU texture memory.
279
+ *
280
+ * Like {@link OccupancyOptions} it does NOT change what is recorded, so it
281
+ * applies to **both live and replay** (the tile texture is decoded in both). A
282
+ * partial memory mitigation for the OOM/crash track (the tile *count* still
283
+ * grows unbounded — capping/recycling is the separate Track-S fix).
284
+ */
285
+ interface FrameTileDisplayOptions {
286
+ /**
287
+ * Display-texture resolution divisor: 1 = full captured resolution, 2 = half
288
+ * (each dimension), 4 = quarter, 8 = eighth. Default 2 (half). Higher = less
289
+ * GPU memory per tile but a blurrier in-AR preview. Independent of the capture
290
+ * `images.resolutionDivisor`.
291
+ */
292
+ divisor: number;
293
+ /**
294
+ * FIFO cap on the **live** frame-tile planes (Step 4 of the 2026-07-03
295
+ * long-session fps plan): adding a tile over the cap removes + disposes the
296
+ * oldest, bounding draw calls / GPU texture memory / scene-graph size for
297
+ * arbitrarily long sessions while keeping the recent-path breadcrumb.
298
+ * `0` = unlimited. Default 100 (a ~5-min walk captures 112–145 frames, so
299
+ * the cap binds on real walks). **Live only** (2026-07-03 interview): in
300
+ * replay the tiles audit coverage of the full recorded path, so the replay
301
+ * wiring stays uncapped regardless of this value.
302
+ */
303
+ maxTiles: number;
304
+ }
305
+ /**
306
+ * Visibility toggles for the live AR debug overlays (Finding B / DB-2 of
307
+ * 2026-06-14-followup-frame-tile-legacy-aspect-and-live-toggle.md).
308
+ *
309
+ * These gate **only what is drawn live during recording** — they never change
310
+ * what is captured (frame blobs, depth samples, occupancy data, GPS events all
311
+ * continue regardless) and, with one exception, they never affect replay
312
+ * (where reviewing the captured overlays is the whole point). Read once at
313
+ * Enter-AR: toggling mid-session applies on the next Enter-AR, not
314
+ * retroactively.
315
+ *
316
+ * The debug overlays default ON, so the group is purely additive — every
317
+ * overlay still renders until the operator opts out. The exception on both
318
+ * counts is {@link VisualizationOptions.statsOverlay}: a perf-measurement tool
319
+ * that defaults OFF and, when on, also runs in replay (see its docs).
320
+ */
321
+ interface VisualizationOptions {
322
+ /** Live frame-tile planes (`FrameTileVisualizer`). Default: true */
323
+ frameTiles: boolean;
324
+ /** Voxel depth cubes (`OccupancyCubesVisualizer`). Default: true */
325
+ occupancyCubes: boolean;
326
+ /** Raw/fused/snapshot GPS+VIO alignment spheres (`GpsEventVisualizer`). Default: true */
327
+ gpsAlignmentMarkers: boolean;
328
+ /** N/E/S/W compass orientation cubes (`createGpsCompassCubes`). Default: true */
329
+ compassCubes: boolean;
330
+ /**
331
+ * Rotate the live in-AR minimap so the user's view direction always points
332
+ * up/forward (heading-up) instead of fixed north-up. Unlike the other flags
333
+ * in this group this is a map-orientation preference, not a show/hide — but it
334
+ * shares their live-only semantics (read at Enter-AR, never affects replay).
335
+ * Default: true. See the 2026-06-29 heading-up plan.
336
+ */
337
+ headingUpMap: boolean;
338
+ /**
339
+ * Performance stats overlay (Stats.js: FPS / frame ms / MB panels) for
340
+ * long-session fps attribution (2026-07-03 long-session fps plan §0).
341
+ * Two exceptions to this group's rules: it is a debug tool, so it defaults
342
+ * **OFF** (must not cost the default path), and unlike the live-only
343
+ * overlays it also runs in **replay** (frame time matters there too).
344
+ * In immersive AR it composites via the dom-overlay feature, so it is
345
+ * invisible when `arCrashIsolation.enableDomOverlay` is off.
346
+ */
347
+ statsOverlay: boolean;
348
+ }
349
+ /**
350
+ * Configuration for live QR detection + RAW recording (decision §0 of the
351
+ * recorder live-QR follow-up,
352
+ * `2026-06-17-followup-recorder-live-qr-next-steps.md`).
353
+ *
354
+ * OPT-IN (`enabled` defaults to `false`): turning it on adds per-frame RGBA
355
+ * capture + a `BarcodeDetector` decode to the session, so it is operator-gated
356
+ * exactly like the heavy `depth`/`images` streams — an existing recording pays
357
+ * nothing. When on, the producer dispatches one RAW `qrDetected/recordQrDetection`
358
+ * action per accepted decode (size + pose are DERIVED on read, never recorded).
359
+ */
360
+ interface QrCaptureOptions {
361
+ /** Whether live QR detection + recording runs. Default: false (opt-in). */
362
+ enabled: boolean;
363
+ /**
364
+ * Capture / detection cadence in ms — the SINGLE cadence owner (the producer
365
+ * runs `minIntervalMs: 0`; this throttles the camera-frame source). Default
366
+ * 125 (~8 Hz), matching the QR demo's `DETECT_INTERVAL_MS`.
367
+ */
368
+ intervalMs: number;
369
+ /**
370
+ * RGBA capture long-edge in px. Larger = more decode range on a small/distant
371
+ * QR but a costlier blit + detect. Default 1024 (the on-device sweep settled
372
+ * here; 512 only decoded small QRs at very close range).
373
+ */
374
+ captureSize: number;
375
+ }
376
+ /**
377
+ * User-configurable recording options.
378
+ * Persisted to localStorage for cross-session consistency.
379
+ */
380
+ interface RecordingOptions {
381
+ /** Depth sampling configuration */
382
+ depth: DepthCaptureOptions;
383
+ /** Image capture configuration */
384
+ images: ImageCaptureOptions;
385
+ /** Diagnostic flags for pre-recording AR crash isolation */
386
+ arCrashIsolation: ArCrashIsolationOptions;
387
+ /** Derived occupancy-grid configuration (voxel size) */
388
+ occupancy: OccupancyOptions;
389
+ /** Frame-tile display-texture resolution (live + replay; capture unchanged) */
390
+ frameTileDisplay: FrameTileDisplayOptions;
391
+ /** Live AR debug-overlay visibility toggles (live-only; replay unaffected) */
392
+ visualization: VisualizationOptions;
393
+ /** Live QR detection + RAW recording configuration (opt-in) */
394
+ qr: QrCaptureOptions;
395
+ /** Compass alignment debug toggles (Stage 0 / Stage C / consistency gate) */
396
+ compassDebug: CompassDebugOptions;
397
+ }
398
+ /**
399
+ * localStorage key for persisted options.
400
+ *
401
+ * **Multi-tab caveat:** All tabs/instances sharing the same origin will
402
+ * read and write this key. In multi-tab or embedded scenarios, concurrent
403
+ * saves can silently overwrite each other. Use a custom `storageKey`
404
+ * parameter in `loadRecordingOptions` / `saveRecordingOptions` to isolate
405
+ * instances when needed.
406
+ */
407
+ declare const STORAGE_KEY = "gps-plus-slam-recorder-options";
408
+ /** Default recording options (all streams enabled) */
409
+ declare const DEFAULT_RECORDING_OPTIONS: RecordingOptions;
410
+ /** Validation constraints for depth options */
411
+ declare const DEPTH_CONSTRAINTS: {
412
+ readonly intervalMs: {
413
+ readonly min: 500;
414
+ readonly max: 5000;
415
+ readonly step: 100;
416
+ };
417
+ readonly gridSize: {
418
+ readonly min: 2;
419
+ readonly max: 64;
420
+ readonly step: 1;
421
+ };
422
+ };
423
+ /** Validation constraints for image options */
424
+ declare const IMAGE_CONSTRAINTS: {
425
+ readonly intervalMs: {
426
+ readonly min: 1000;
427
+ readonly max: 10000;
428
+ readonly step: 500;
429
+ };
430
+ readonly quality: {
431
+ readonly min: 0.3;
432
+ readonly max: 1;
433
+ readonly step: 0.1;
434
+ };
435
+ readonly resolutionDivisor: {
436
+ readonly min: 1;
437
+ readonly max: 8;
438
+ readonly step: 1;
439
+ };
440
+ };
441
+ /**
442
+ * Validation constraints for the motion-filter (blurry-frame gate) thresholds.
443
+ *
444
+ * The velocity ranges (0.05–5) bracket the plausible scanning regime: below
445
+ * ~0.05 the gate would reject almost everything; above ~5 rad/s ≈ 286°/s (or
446
+ * 5 m/s) it would never reject, so the gate would be inert. `maxWaitMs` is
447
+ * clamped to 0.5–20 s — the never-calm fallback must always be able to fire.
448
+ * All three back a (currently advanced/hidden) settings slider, so a corrupt
449
+ * stored value can never disable capture. The default thresholds themselves are
450
+ * placeholders pending on-device field tuning (plan §7).
451
+ */
452
+ declare const MOTION_FILTER_CONSTRAINTS: {
453
+ readonly maxAngularVelocity: {
454
+ readonly min: 0.05;
455
+ readonly max: 5;
456
+ readonly step: 0.05;
457
+ };
458
+ readonly maxLinearVelocity: {
459
+ readonly min: 0.05;
460
+ readonly max: 5;
461
+ readonly step: 0.05;
462
+ };
463
+ readonly maxWaitMs: {
464
+ readonly min: 500;
465
+ readonly max: 20000;
466
+ readonly step: 500;
467
+ };
468
+ };
469
+ /**
470
+ * Validation constraints for the image-quality (blur/blackness) gate thresholds.
471
+ *
472
+ * `blurRelativeThreshold` (`k` in `sharpness < k·median`) is clamped to
473
+ * 0.05–0.95: it is a fraction of the recent sharpness median, so values must sit
474
+ * strictly inside (0, 1) — at ~0 the blur check never rejects, near 1 it rejects
475
+ * almost everything. `minMeanLuminance` (the absolute black cutoff on a 0–255
476
+ * luma scale) is clamped to 0–128: 0 disables the black check, and a cutoff
477
+ * above mid-grey would reject normally-lit frames. `maxWaitMs` mirrors the motion
478
+ * gate's range (0.5–20 s) so the never-good fallback can always fire. All back a
479
+ * (currently advanced/hidden) settings slider, so a corrupt stored value can
480
+ * never disable capture. The default thresholds are placeholders pending
481
+ * on-device field tuning (plan §5, §10).
482
+ */
483
+ declare const QUALITY_FILTER_CONSTRAINTS: {
484
+ readonly blurRelativeThreshold: {
485
+ readonly min: 0.05;
486
+ readonly max: 0.95;
487
+ readonly step: 0.05;
488
+ };
489
+ readonly minMeanLuminance: {
490
+ readonly min: 0;
491
+ readonly max: 128;
492
+ readonly step: 1;
493
+ };
494
+ readonly maxWaitMs: {
495
+ readonly min: 500;
496
+ readonly max: 20000;
497
+ readonly step: 500;
498
+ };
499
+ };
500
+ /**
501
+ * Validation constraints for occupancy options.
502
+ *
503
+ * `cellSizeM` is clamped to 1–20 cm. The floor exists because cell count (and
504
+ * therefore the cube `InstancedMesh`, the grid `Map`, and the COLMAP
505
+ * `points3D` row count) scales as 1/cellSize³ — sub-centimetre voxels are both
506
+ * a memory/perf cliff on a phone and below the depth sensor's noise floor.
507
+ * Step is 1 cm (the settings slider operates in cm).
508
+ *
509
+ * `minConfidence` is clamped to 1–10 (integer). 1 disables the filter (legacy
510
+ * behaviour: a single observation counts as occupied); the ceiling exists
511
+ * because real surfaces accumulate only a handful of observations per second
512
+ * of dwell, so a floor above ~10 would start hiding genuine geometry.
513
+ */
514
+ declare const OCCUPANCY_CONSTRAINTS: {
515
+ readonly cellSizeM: {
516
+ readonly min: 0.01;
517
+ readonly max: 0.2;
518
+ readonly step: 0.01;
519
+ };
520
+ readonly minConfidence: {
521
+ readonly min: 1;
522
+ readonly max: 10;
523
+ readonly step: 1;
524
+ };
525
+ readonly occluderRadiusM: {
526
+ readonly min: 0;
527
+ readonly max: 200;
528
+ readonly step: 5;
529
+ };
530
+ };
531
+ /**
532
+ * Validation constraints for the frame-tile display-resolution divisor.
533
+ *
534
+ * Clamped to 1–8 (full down to one-eighth per dimension), mirroring the capture
535
+ * `IMAGE_CONSTRAINTS.resolutionDivisor` range so the settings slider behaves the
536
+ * same. The intended stops are 1, 2, 4, 8 (full / half / quarter / eighth); the
537
+ * divisor is rounded to an integer so the resize target dimensions stay clean.
538
+ */
539
+ declare const FRAME_TILE_DISPLAY_CONSTRAINTS: {
540
+ readonly divisor: {
541
+ readonly min: 1;
542
+ readonly max: 8;
543
+ readonly step: 1;
544
+ };
545
+ readonly maxTiles: {
546
+ readonly min: 0;
547
+ readonly max: 2000;
548
+ readonly step: 10;
549
+ };
550
+ };
551
+ /**
552
+ * Validation constraints for QR-capture options.
553
+ *
554
+ * `intervalMs` is clamped to 50–1000 ms (20 Hz down to 1 Hz): below ~50 ms the
555
+ * detector cannot keep up and frames just queue; above 1 s tracking feels dead.
556
+ * `captureSize` is clamped to 256–2048 px: under 256 even a near QR loses its
557
+ * modules; over 2048 the blit + decode cost is not worth it on a phone. Both
558
+ * back a settings slider so a corrupt stored value can never break capture.
559
+ */
560
+ declare const QR_CONSTRAINTS: {
561
+ readonly intervalMs: {
562
+ readonly min: 50;
563
+ readonly max: 1000;
564
+ readonly step: 25;
565
+ };
566
+ readonly captureSize: {
567
+ readonly min: 256;
568
+ readonly max: 2048;
569
+ readonly step: 128;
570
+ };
571
+ };
572
+ /**
573
+ * Validate and normalize AR crash isolation flags.
574
+ * Missing or invalid values fall back to defaults.
575
+ */
576
+ declare function validateArCrashIsolationOptions(options: Partial<ArCrashIsolationOptions>): ArCrashIsolationOptions;
577
+ /**
578
+ * Validate and normalize the compass alignment debug toggles. Boolean-or-default
579
+ * per field; a missing/corrupted/pre-feature value falls back to the OFF default
580
+ * so a bad persisted value can never silently turn an alignment override ON.
581
+ */
582
+ declare function validateCompassDebugOptions(options: Partial<CompassDebugOptions>): CompassDebugOptions;
583
+ /**
584
+ * Validate and normalize the live debug-overlay visibility toggles.
585
+ * Each field is boolean-or-default (same policy as the AR-crash-isolation
586
+ * flags): a missing, corrupted, or pre-feature persisted value falls back to
587
+ * the ON default so an overlay is never silently disabled by bad input.
588
+ */
589
+ declare function validateVisualizationOptions(options: Partial<VisualizationOptions>): VisualizationOptions;
590
+ /**
591
+ * Validate and normalize QR-capture options. `enabled` is boolean-or-default
592
+ * (a corrupt/pre-feature value falls back to the OFF default so QR never
593
+ * silently turns ON); `intervalMs`/`captureSize` are clamped to
594
+ * {@link QR_CONSTRAINTS}, with a `Number.isFinite` guard so a stored `NaN`
595
+ * (which is `typeof 'number'` and survives `clamp`) falls back to the default
596
+ * rather than breaking the camera-frame source.
597
+ */
598
+ declare function validateQrOptions(options: Partial<QrCaptureOptions>): QrCaptureOptions;
599
+ /**
600
+ * Validate and normalize depth options.
601
+ * Invalid values are clamped to valid ranges.
602
+ */
603
+ declare function validateDepthOptions(options: Partial<DepthCaptureOptions>): DepthCaptureOptions;
604
+ /**
605
+ * Validate and normalize the motion-filter (blurry-frame gate) options.
606
+ * `enabled` is boolean-or-default; the three numeric thresholds are clamped to
607
+ * {@link MOTION_FILTER_CONSTRAINTS} with a `Number.isFinite` guard (a stored
608
+ * `NaN` is `typeof 'number'` and would survive `clamp`). A missing group
609
+ * default-fills entirely — a pre-feature persisted options object that lacks
610
+ * `motionFilter` therefore loads with the gate enabled rather than crashing.
611
+ */
612
+ declare function validateMotionFilterOptions(options: Partial<MotionFilterConfig>): MotionFilterConfig;
613
+ /**
614
+ * Validate and normalize the image-quality (blur/blackness gate) options. Same
615
+ * policy as {@link validateMotionFilterOptions}: `enabled` is boolean-or-default;
616
+ * the three numeric thresholds are clamped to {@link QUALITY_FILTER_CONSTRAINTS}
617
+ * with a `Number.isFinite` guard (a stored `NaN` is `typeof 'number'` and would
618
+ * survive `clamp`). A missing group default-fills entirely — a pre-feature
619
+ * persisted options object that lacks `qualityFilter` loads with the gate
620
+ * disabled (the safe default) rather than crashing.
621
+ */
622
+ declare function validateQualityFilterOptions(options: Partial<QualityFilterConfig>): QualityFilterConfig;
623
+ /**
624
+ * Validate and normalize image options.
625
+ * Invalid values are clamped to valid ranges.
626
+ */
627
+ declare function validateImageOptions(options: Partial<ImageCaptureOptions>): ImageCaptureOptions;
628
+ declare function validateOccupancyOptions(options: Partial<OccupancyOptions>): OccupancyOptions;
629
+ /**
630
+ * Validate and normalize frame-tile display options. `divisor` is clamped to
631
+ * {@link FRAME_TILE_DISPLAY_CONSTRAINTS} and rounded to an integer, with a
632
+ * `Number.isFinite` guard so a stored `NaN` (which is `typeof 'number'` and
633
+ * survives `clamp`) falls back to the default rather than producing a broken
634
+ * resize target.
635
+ */
636
+ declare function validateFrameTileDisplayOptions(options: Partial<FrameTileDisplayOptions>): FrameTileDisplayOptions;
637
+ /**
638
+ * Validate and normalize a full RecordingOptions object.
639
+ * Merges with defaults and clamps invalid values.
640
+ */
641
+ declare function validateRecordingOptions(options: RecordingOptionsInput): RecordingOptions;
642
+ /**
643
+ * Load recording options from localStorage.
644
+ * Returns defaults if no saved options exist or parsing fails.
645
+ * Validates and merges with defaults to handle schema evolution.
646
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
647
+ */
648
+ declare function loadRecordingOptions(storageKey?: string): RecordingOptions;
649
+ /**
650
+ * Save recording options to localStorage.
651
+ * Options are validated before saving.
652
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
653
+ */
654
+ declare function saveRecordingOptions(options: RecordingOptions, storageKey?: string): void;
655
+ /**
656
+ * Reset recording options to defaults.
657
+ * Clears localStorage and returns default options.
658
+ * @param storageKey - Optional custom localStorage key (defaults to STORAGE_KEY).
659
+ */
660
+ declare function resetRecordingOptions(storageKey?: string): RecordingOptions;
661
+ /**
662
+ * Create a deep copy of recording options.
663
+ * Useful for creating mutable copies of the frozen defaults.
664
+ */
665
+ declare function cloneRecordingOptions(options: RecordingOptions): RecordingOptions;
666
+ //#endregion
667
+ export { validateImageOptions as A, loadRecordingOptions as C, validateCompassDebugOptions as D, validateArCrashIsolationOptions as E, validateRecordingOptions as F, validateVisualizationOptions as I, validateOccupancyOptions as M, validateQrOptions as N, validateDepthOptions as O, validateQualityFilterOptions as P, cloneRecordingOptions as S, saveRecordingOptions as T, QrCaptureOptions as _, DepthCaptureOptions as a, STORAGE_KEY as b, IMAGE_CONSTRAINTS as c, OCCUPANCY_CONSTRAINTS as d, OccluderDebugStyle as f, QUALITY_FILTER_CONSTRAINTS as g, QR_CONSTRAINTS as h, DEPTH_CONSTRAINTS as i, validateMotionFilterOptions as j, validateFrameTileDisplayOptions as k, ImageCaptureOptions as l, OccupancyOptions as m, CompassDebugOptions as n, FRAME_TILE_DISPLAY_CONSTRAINTS as o, OccluderMeshMode as p, DEFAULT_RECORDING_OPTIONS as r, FrameTileDisplayOptions as s, ArCrashIsolationOptions as t, MOTION_FILTER_CONSTRAINTS as u, RecordingOptions as v, resetRecordingOptions as w, VisualizationOptions as x, RecordingOptionsInput as y };
@@ -1,5 +1,5 @@
1
- import { L as CombinedRootState } from "./create-slam-app-store-Ce2FMKCp.js";
2
- import { i as RecordedAction } from "./zip-reader-Q2ue6zlC.js";
1
+ import { N as CombinedRootState } from "./create-slam-app-store-D3nzh9Wb.js";
2
+ import { i as RecordedAction } from "./zip-reader-CvruaGvD.js";
3
3
 
4
4
  //#region ../src/state/recording-replayer.d.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { i as DepthSample } from "./ar-types-BckI1E-O.js";
2
- import { p as RecordingOptions } from "./recording-options-D93kksJU.js";
1
+ import { i as DepthSample } from "./ar-types-Cc5yvBwn.js";
2
+ import { v as RecordingOptions } from "./recording-options-vASCFzc5.js";
3
3
  import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
4
4
 
5
5
  //#region ../src/state/recording-slice.d.ts