@photivra/engine 2.17.0 → 2.19.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 (288) hide show
  1. package/CHANGELOG.md +116 -1
  2. package/CITATION.cff +1 -1
  3. package/README.md +6 -6
  4. package/SECURITY.md +1 -1
  5. package/dist/camera/sensor-equivalence.d.ts +156 -0
  6. package/dist/camera/sensor-equivalence.js +208 -0
  7. package/dist/camera/sensor-equivalence.js.map +1 -0
  8. package/dist/capture/focus-control.js +2 -75
  9. package/dist/capture/focus-control.js.map +1 -1
  10. package/dist/capture/native-environment-lean.d.ts +1 -0
  11. package/dist/capture/native-environment-lean.js +1 -1
  12. package/dist/capture/native-environment-lean.js.map +1 -1
  13. package/dist/capture/native-environment-optical-stage.d.ts +1 -0
  14. package/dist/capture/native-environment-optical-stage.js +2 -5
  15. package/dist/capture/native-environment-optical-stage.js.map +1 -1
  16. package/dist/capture/native-environment-raw.js +1 -5
  17. package/dist/capture/native-environment-raw.js.map +1 -1
  18. package/dist/capture/native-environment-tabulated.d.ts +5 -0
  19. package/dist/capture/native-environment-tabulated.js +1 -1
  20. package/dist/capture/native-environment-tabulated.js.map +1 -1
  21. package/dist/capture/release-sequence.js +2 -47
  22. package/dist/capture/release-sequence.js.map +1 -1
  23. package/dist/color/white-balance.d.ts +2 -0
  24. package/dist/color/white-balance.js +3 -56
  25. package/dist/color/white-balance.js.map +1 -1
  26. package/dist/composition/image-formation-plan.d.ts +1 -0
  27. package/dist/composition/image-formation-plan.js +3 -49
  28. package/dist/composition/image-formation-plan.js.map +1 -1
  29. package/dist/core/evidence-provenance.js +1 -16
  30. package/dist/core/evidence-provenance.js.map +1 -1
  31. package/dist/core/record-validation.d.ts +54 -0
  32. package/dist/core/record-validation.js +176 -0
  33. package/dist/core/record-validation.js.map +1 -1
  34. package/dist/core/scientific-assurance.js +1 -18
  35. package/dist/core/scientific-assurance.js.map +1 -1
  36. package/dist/core/shared-helpers.d.ts +33 -0
  37. package/dist/core/shared-helpers.js +34 -0
  38. package/dist/core/shared-helpers.js.map +1 -0
  39. package/dist/core/spectral-composition.js +1 -36
  40. package/dist/core/spectral-composition.js.map +1 -1
  41. package/dist/core/spectral.js +1 -19
  42. package/dist/core/spectral.js.map +1 -1
  43. package/dist/core/version.d.ts +1 -1
  44. package/dist/core/version.js +1 -1
  45. package/dist/core/version.js.map +1 -1
  46. package/dist/equipment/exposure-capabilities.d.ts +1 -0
  47. package/dist/equipment/exposure-capabilities.js +2 -36
  48. package/dist/equipment/exposure-capabilities.js.map +1 -1
  49. package/dist/equipment/ideal-lens.d.ts +25 -0
  50. package/dist/equipment/ideal-lens.js +21 -0
  51. package/dist/equipment/ideal-lens.js.map +1 -0
  52. package/dist/equipment/iso-capabilities.js +2 -49
  53. package/dist/equipment/iso-capabilities.js.map +1 -1
  54. package/dist/equipment/metering-capabilities.js +1 -26
  55. package/dist/equipment/metering-capabilities.js.map +1 -1
  56. package/dist/equipment/release-capabilities.js +1 -53
  57. package/dist/equipment/release-capabilities.js.map +1 -1
  58. package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
  59. package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
  60. package/dist/exposure/exposure-duration-control.js +1 -16
  61. package/dist/exposure/exposure-duration-control.js.map +1 -1
  62. package/dist/exposure/exposure-mode-resolver.js +1 -17
  63. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  64. package/dist/exposure/filtered-exposure-time.d.ts +93 -0
  65. package/dist/exposure/filtered-exposure-time.js +129 -0
  66. package/dist/exposure/filtered-exposure-time.js.map +1 -0
  67. package/dist/exposure/flash-ttl.d.ts +1 -0
  68. package/dist/exposure/flash-ttl.js +1 -1
  69. package/dist/exposure/flash-ttl.js.map +1 -1
  70. package/dist/exposure/flash.js +1 -49
  71. package/dist/exposure/flash.js.map +1 -1
  72. package/dist/exposure/metering-scene-radiance.js +1 -25
  73. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  74. package/dist/exposure/metering-target.js +1 -30
  75. package/dist/exposure/metering-target.js.map +1 -1
  76. package/dist/exposure/metering-temporal.js +1 -8
  77. package/dist/exposure/metering-temporal.js.map +1 -1
  78. package/dist/exposure/metering.js +1 -72
  79. package/dist/exposure/metering.js.map +1 -1
  80. package/dist/exposure/program-line.js +1 -45
  81. package/dist/exposure/program-line.js.map +1 -1
  82. package/dist/facade/catalogue-lens-signal.d.ts +94 -0
  83. package/dist/facade/catalogue-lens-signal.js +362 -0
  84. package/dist/facade/catalogue-lens-signal.js.map +1 -0
  85. package/dist/facade/defocus-image-space-provider.js +5 -2
  86. package/dist/facade/defocus-image-space-provider.js.map +1 -1
  87. package/dist/facade/develop-joined-parts.d.ts +29 -0
  88. package/dist/facade/develop-joined-parts.js +33 -0
  89. package/dist/facade/develop-joined-parts.js.map +1 -0
  90. package/dist/facade/display-view-lens-signal.d.ts +32 -1
  91. package/dist/facade/display-view-lens-signal.js +85 -10
  92. package/dist/facade/display-view-lens-signal.js.map +1 -1
  93. package/dist/facade/expected-signal-setup.d.ts +8 -0
  94. package/dist/facade/expected-signal-setup.js +7 -0
  95. package/dist/facade/expected-signal-setup.js.map +1 -1
  96. package/dist/facade/expected-signal.d.ts +5 -0
  97. package/dist/facade/expected-signal.js +5 -1
  98. package/dist/facade/expected-signal.js.map +1 -1
  99. package/dist/facade/generic-lens-capture.d.ts +5 -2
  100. package/dist/facade/generic-lens-capture.js +5 -2
  101. package/dist/facade/generic-lens-capture.js.map +1 -1
  102. package/dist/facade/simulate-capture.d.ts +67 -8
  103. package/dist/facade/simulate-capture.js +262 -126
  104. package/dist/facade/simulate-capture.js.map +1 -1
  105. package/dist/facade/simulate-display-view.js +1 -1
  106. package/dist/facade/simulate-display-view.js.map +1 -1
  107. package/dist/gpu/chart-composite-gpu.js +1 -3
  108. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  109. package/dist/gpu/chart-radiance-gpu.js +1 -5
  110. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  111. package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
  112. package/dist/gpu/display-view-quality-gpu.js +4 -8
  113. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  114. package/dist/gpu/display-view-speed-gpu.js +3 -25
  115. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  116. package/dist/gpu/sensor-stage-gpu.js +1 -5
  117. package/dist/gpu/sensor-stage-gpu.js.map +1 -1
  118. package/dist/gpu/webgpu-runtime.d.ts +2 -0
  119. package/dist/gpu/webgpu-runtime.js +3 -0
  120. package/dist/gpu/webgpu-runtime.js.map +1 -1
  121. package/dist/index.d.ts +6 -1
  122. package/dist/index.js +5 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/motion/camera-rotation.js +1 -6
  125. package/dist/motion/camera-rotation.js.map +1 -1
  126. package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
  127. package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
  128. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  129. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
  130. package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
  131. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  132. package/dist/motion/capture-rotation-trajectory.js +2 -17
  133. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  134. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
  135. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
  136. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  137. package/dist/motion/extended-object-projection.js +5 -40
  138. package/dist/motion/extended-object-projection.js.map +1 -1
  139. package/dist/optics/atmospheric-haze.js +1 -7
  140. package/dist/optics/atmospheric-haze.js.map +1 -1
  141. package/dist/optics/brown-conrady-distortion.js +1 -7
  142. package/dist/optics/brown-conrady-distortion.js.map +1 -1
  143. package/dist/optics/complex-pupil-psf.d.ts +1 -0
  144. package/dist/optics/complex-pupil-psf.js +2 -84
  145. package/dist/optics/complex-pupil-psf.js.map +1 -1
  146. package/dist/optics/focus-state.js +1 -11
  147. package/dist/optics/focus-state.js.map +1 -1
  148. package/dist/optics/front-of-lens-filter.d.ts +5 -0
  149. package/dist/optics/front-of-lens-filter.js +3 -65
  150. package/dist/optics/front-of-lens-filter.js.map +1 -1
  151. package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
  152. package/dist/optics/generic-nd-filter-presets.js +48 -0
  153. package/dist/optics/generic-nd-filter-presets.js.map +1 -0
  154. package/dist/optics/illumination-vignetting.js +1 -6
  155. package/dist/optics/illumination-vignetting.js.map +1 -1
  156. package/dist/optics/lens-psf-profile.d.ts +4 -1
  157. package/dist/optics/lens-psf-profile.js +12 -111
  158. package/dist/optics/lens-psf-profile.js.map +1 -1
  159. package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
  160. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
  161. package/dist/optics/pupil-vignetting.js +1 -7
  162. package/dist/optics/pupil-vignetting.js.map +1 -1
  163. package/dist/optics/radial-distortion.js +1 -6
  164. package/dist/optics/radial-distortion.js.map +1 -1
  165. package/dist/optics/scene-to-sensor-irradiance.js +4 -96
  166. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  167. package/dist/optics/stray-light.d.ts +1 -0
  168. package/dist/optics/stray-light.js +1 -1
  169. package/dist/optics/stray-light.js.map +1 -1
  170. package/dist/optics/zernike-wavefront.js +1 -7
  171. package/dist/optics/zernike-wavefront.js.map +1 -1
  172. package/dist/output/capture-geometry.js +1 -8
  173. package/dist/output/capture-geometry.js.map +1 -1
  174. package/dist/output/developed-lens-corrections.d.ts +62 -0
  175. package/dist/output/developed-lens-corrections.js +135 -0
  176. package/dist/output/developed-lens-corrections.js.map +1 -0
  177. package/dist/output/generic-lens-corrections.d.ts +2 -6
  178. package/dist/output/generic-lens-corrections.js +3 -6
  179. package/dist/output/generic-lens-corrections.js.map +1 -1
  180. package/dist/output/geometric-transforms.js +1 -4
  181. package/dist/output/geometric-transforms.js.map +1 -1
  182. package/dist/output/native-capture-sdr.d.ts +2 -2
  183. package/dist/output/native-capture-sdr.js +3 -2
  184. package/dist/output/native-capture-sdr.js.map +1 -1
  185. package/dist/processing/development-detail.d.ts +29 -0
  186. package/dist/processing/development-detail.js +128 -107
  187. package/dist/processing/development-detail.js.map +1 -1
  188. package/dist/schema/illumination-temporal.js +3 -72
  189. package/dist/schema/illumination-temporal.js.map +1 -1
  190. package/dist/schema/illumination.d.ts +1 -0
  191. package/dist/schema/illumination.js +2 -65
  192. package/dist/schema/illumination.js.map +1 -1
  193. package/dist/schema/scene-radiance-temporal.js +2 -14
  194. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  195. package/dist/schema/scene-radiance.js +2 -60
  196. package/dist/schema/scene-radiance.js.map +1 -1
  197. package/dist/schema/validation.d.ts +2 -0
  198. package/dist/schema/validation.js +2 -17
  199. package/dist/schema/validation.js.map +1 -1
  200. package/dist/sensor/accumulated-charge.js +2 -59
  201. package/dist/sensor/accumulated-charge.js.map +1 -1
  202. package/dist/sensor/architecture.js +1 -16
  203. package/dist/sensor/architecture.js.map +1 -1
  204. package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
  205. package/dist/sensor/camera-saturation-capacity.js +3 -55
  206. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  207. package/dist/sensor/capture-color-sampling-binding.js +1 -26
  208. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  209. package/dist/sensor/capture-mode-timing.js +1 -39
  210. package/dist/sensor/capture-mode-timing.js.map +1 -1
  211. package/dist/sensor/capture-mode.js +1 -23
  212. package/dist/sensor/capture-mode.js.map +1 -1
  213. package/dist/sensor/color-sampling.js +1 -26
  214. package/dist/sensor/color-sampling.js.map +1 -1
  215. package/dist/sensor/constant-rate-temporal-integration.js +2 -46
  216. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  217. package/dist/sensor/dark-current.js +2 -45
  218. package/dist/sensor/dark-current.js.map +1 -1
  219. package/dist/sensor/eqe-electron-rate.js +2 -35
  220. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  221. package/dist/sensor/exposure-window.d.ts +5 -0
  222. package/dist/sensor/exposure-window.js +7 -22
  223. package/dist/sensor/exposure-window.js.map +1 -1
  224. package/dist/sensor/iso-gain.js +1 -7
  225. package/dist/sensor/iso-gain.js.map +1 -1
  226. package/dist/sensor/iso-signal-chain.js +1 -43
  227. package/dist/sensor/iso-signal-chain.js.map +1 -1
  228. package/dist/sensor/optical-stack.js +1 -25
  229. package/dist/sensor/optical-stack.js.map +1 -1
  230. package/dist/sensor/photon-energy.js +1 -26
  231. package/dist/sensor/photon-energy.js.map +1 -1
  232. package/dist/sensor/physical-charge-capacity.js +3 -77
  233. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  234. package/dist/sensor/radiometry-readiness.js +2 -23
  235. package/dist/sensor/radiometry-readiness.js.map +1 -1
  236. package/dist/sensor/raw-readout.d.ts +3 -0
  237. package/dist/sensor/raw-readout.js +4 -66
  238. package/dist/sensor/raw-readout.js.map +1 -1
  239. package/dist/sensor/raw-reconstruction.js +2 -64
  240. package/dist/sensor/raw-reconstruction.js.map +1 -1
  241. package/dist/sensor/readout-exposure-linkage.js +1 -9
  242. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  243. package/dist/sensor/readout-timing.js +3 -57
  244. package/dist/sensor/readout-timing.js.map +1 -1
  245. package/dist/sensor/response-application-compatibility.d.ts +2 -0
  246. package/dist/sensor/response-application-compatibility.js +3 -29
  247. package/dist/sensor/response-application-compatibility.js.map +1 -1
  248. package/dist/sensor/response-operating-range.d.ts +1 -0
  249. package/dist/sensor/response-operating-range.js +3 -79
  250. package/dist/sensor/response-operating-range.js.map +1 -1
  251. package/dist/sensor/responsivity-photocurrent.js +4 -108
  252. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  253. package/dist/sensor/sampling-aperture.js +1 -25
  254. package/dist/sensor/sampling-aperture.js.map +1 -1
  255. package/dist/sensor/spatial-sample-reduction.js +2 -19
  256. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  257. package/dist/sensor/spatial-sampling-quadrature.js +1 -3
  258. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  259. package/dist/sensor/spatio-spectral-reduction.js +1 -18
  260. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  261. package/dist/sensor/spectral-coverage.d.ts +10 -1
  262. package/dist/sensor/spectral-coverage.js +1 -1
  263. package/dist/sensor/spectral-coverage.js.map +1 -1
  264. package/dist/sensor/spectral-quadrature.js +2 -35
  265. package/dist/sensor/spectral-quadrature.js.map +1 -1
  266. package/dist/sensor/spectral-response.js +1 -47
  267. package/dist/sensor/spectral-response.js.map +1 -1
  268. package/dist/stabilization/camera-shake.js +1 -6
  269. package/dist/stabilization/camera-shake.js.map +1 -1
  270. package/dist/stabilization/system.js +2 -80
  271. package/dist/stabilization/system.js.map +1 -1
  272. package/docs/AGENT_GUIDE.md +4 -0
  273. package/docs/API_REFERENCE.md +69 -2
  274. package/docs/QUICK_START.md +136 -6
  275. package/docs/USAGE.md +89 -3
  276. package/docs/api/camera-sensor-equivalence.md +209 -0
  277. package/docs/api/core-version.md +1 -1
  278. package/docs/api/equipment-ideal-lens.md +26 -0
  279. package/docs/api/exports.json +118 -3
  280. package/docs/api/exposure-filtered-exposure-time.md +105 -0
  281. package/docs/api/facade-develop-joined-parts.md +32 -0
  282. package/docs/api/facade-simulate-capture.md +62 -8
  283. package/docs/api/optics-generic-nd-filter-presets.md +34 -0
  284. package/docs/api/optics-lens-psf-profile.md +3 -1
  285. package/docs/api/output-developed-lens-corrections.md +12 -0
  286. package/docs/api/output-generic-lens-corrections.md +0 -9
  287. package/llms.txt +3 -0
  288. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/stabilization/system.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic image stabilization: profiles, disturbance trajectories, the stabilized rotation and its\n * effect on capture timing samples.\n *\n * The parsers validate untrusted input and return the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @see docs/STABILIZATION.md for the equations, units, coordinate conventions, known blockers and\n * support limits.\n */\n\nimport {\n approximationResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceBackedFact,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n InvalidScientificInputError,\n requirePositiveInteger\n} from \"../core/validation.js\";\nimport type {\n RasterPoint\n} from \"../output/capture-geometry.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputKeys, requireInputObject, rejectUnknownFields, rejectUnknownVariantFields } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION =\n \"0.1.0\" as const;\n\nexport type StabilizationRotationAxis =\n | \"pitch\"\n | \"yaw\"\n | \"roll\";\n\nexport type PhysicalStabilizationArchitecture =\n | \"off\"\n | \"sensor-shift\"\n | \"lens-optical\"\n | \"coordinated-physical\";\n\nexport type StabilizationCaptureKind =\n | \"still\"\n | \"video\";\n\nexport interface StabilizationAngularStateRad {\n pitch: number;\n yaw: number;\n roll: number;\n}\n\nexport interface StabilizationDisturbanceSample {\n timeSecondsFromCaptureReference:\n number;\n angularDisplacementRad:\n StabilizationAngularStateRad;\n}\n\nexport interface StabilizationDisturbanceTrajectory {\n version:\n typeof STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION;\n trajectoryId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n samples:\n readonly StabilizationDisturbanceSample[];\n initialAngularDisplacementIsZero:\n true;\n cameraTranslationIncluded:\n false;\n subjectMotionIncluded:\n false;\n supportStateEncoded:\n false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface StabilizationAxisResponseProfile {\n axis: StabilizationRotationAxis;\n correctionGain:\n EvidenceBackedFact<number>;\n latencySeconds:\n EvidenceBackedFact<number>;\n maximumCorrectionAngleRad:\n EvidenceBackedFact<number>;\n}\n\nexport type StabilizationPanningPolicy =\n | {\n kind: \"none\";\n }\n | {\n kind:\n \"declared-axis-bypass\";\n axis:\n StabilizationRotationAxis;\n evidence:\n readonly EvidenceProvenance[];\n };\n\nexport interface StabilizationCoordinatedAllocation {\n bodyFraction: number;\n lensFraction: number;\n evidence: readonly EvidenceProvenance[];\n totalCorrectionAppliedOnce:\n true;\n}\n\nexport interface StabilizationSystemProfile {\n schemaVersion:\n typeof STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n profileKind:\n \"generic-synthetic\";\n scientificStatus:\n \"approximation\";\n architecture:\n PhysicalStabilizationArchitecture;\n captureKind:\n StabilizationCaptureKind;\n axisResponses:\n readonly StabilizationAxisResponseProfile[];\n panningPolicy:\n StabilizationPanningPolicy;\n coordinatedAllocation?:\n StabilizationCoordinatedAllocation;\n controlTransientModeled: false;\n spontaneousDriftModeled: false;\n cameraTranslationCorrectionModeled:\n false;\n digitalStabilizationIncluded:\n false;\n supportPolicyIncluded: false;\n stopRatingUsedAsDynamicResponse:\n false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface CalculateStabilizedRotationTrajectoryInput {\n disturbance:\n StabilizationDisturbanceTrajectory;\n profile:\n StabilizationSystemProfile;\n captureKind:\n StabilizationCaptureKind;\n}\n\nexport interface StabilizationAxisResolution {\n axis: StabilizationRotationAxis;\n disturbanceAngleRad: number;\n delayedMeasuredAngleRad: number;\n requestedCorrectionAngleRad:\n number;\n appliedCorrectionAngleRad:\n number;\n residualAngleRad: number;\n correctionGain: number;\n latencySeconds: number;\n maximumCorrectionAngleRad:\n number;\n bypassedForDeclaredPan:\n boolean;\n correctionLimitReached:\n boolean;\n}\n\nexport interface StabilizedRotationSample {\n timeSecondsFromCaptureReference:\n number;\n disturbanceAngularDisplacementRad:\n StabilizationAngularStateRad;\n appliedCorrectionAngularDisplacementRad:\n StabilizationAngularStateRad;\n residualAngularDisplacementRad:\n StabilizationAngularStateRad;\n axes:\n readonly StabilizationAxisResolution[];\n}\n\nexport interface StabilizedRotationTrajectory {\n profileId: string;\n profileVersion: string;\n trajectoryId: string;\n architecture:\n PhysicalStabilizationArchitecture;\n captureKind:\n StabilizationCaptureKind;\n timeReference:\n \"first-opening-boundary-phase\";\n samples:\n readonly StabilizedRotationSample[];\n correctionModel:\n \"delayed-linear-image-equivalent-angular-response\";\n supportStateConsumed: false;\n translationCorrectionModeled:\n false;\n digitalStabilizationApplied:\n false;\n digitalStabilizationOwnedBy:\n \"downstream-geometric-correction-composition\";\n coordinatedCorrectionDoubleCounted:\n false;\n zeroDisturbanceCanCreateMotion:\n false;\n}\n\nexport interface CalculateStabilizedCaptureTemporalSamplesInput {\n disturbance:\n StabilizationDisturbanceTrajectory;\n profile:\n StabilizationSystemProfile;\n captureKind:\n StabilizationCaptureKind;\n timing:\n ResolvedCaptureModeTiming;\n samplePointsNative:\n readonly RasterPoint[];\n temporalSampleCount: number;\n}\n\nexport interface StabilizedCaptureTemporalNode {\n temporalSampleIndex: number;\n localExposurePhase: number;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n stabilization:\n StabilizedRotationSample;\n}\n\nexport interface StabilizedCaptureTemporalPoint {\n destinationPointNative:\n RasterPoint;\n localExposureWindow: {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n nodes:\n readonly StabilizedCaptureTemporalNode[];\n}\n\nexport interface StabilizedCaptureTemporalSamples {\n profileId: string;\n trajectoryId: string;\n captureModeId: string;\n timingProfileId: string;\n captureKind:\n StabilizationCaptureKind;\n architecture:\n PhysicalStabilizationArchitecture;\n timeReference:\n \"first-opening-boundary-phase\";\n quadratureScheme:\n \"uniform-midpoint\";\n temporalSampleCount: number;\n points:\n readonly StabilizedCaptureTemporalPoint[];\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n supportStateConsumed: false;\n translationCorrectionModeled:\n false;\n digitalStabilizationApplied:\n false;\n}\n\nconst AXES =\n new Set<StabilizationRotationAxis>([\n \"pitch\",\n \"yaw\",\n \"roll\"\n ]);\n\nconst ARCHITECTURES =\n new Set<PhysicalStabilizationArchitecture>([\n \"off\",\n \"sensor-shift\",\n \"lens-optical\",\n \"coordinated-physical\"\n ]);\n\nconst CAPTURE_KINDS =\n new Set<StabilizationCaptureKind>([\n \"still\",\n \"video\"\n ]);\n\nfunction requireRecord(\n value: unknown,\n path: string,\n allowedKeys: readonly string[] | null\n): UnknownRecord {\n if (\n typeof value !== \"object\" ||\n value === null ||\n Array.isArray(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be an object.\"\n );\n }\n if (allowedKeys !== null) rejectUnknownFields(value, allowedKeys, path);\n return value as UnknownRecord;\n}\n\nfunction requireNonEmptyString(\n value: unknown,\n path: string\n): string {\n if (\n typeof value !== \"string\" ||\n value.trim().length === 0\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must be a non-empty string.\"\n );\n }\n return value.trim();\n}\n\nfunction requireFinite(\n value: unknown,\n path: string\n): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value)\n ) {\n throw new InvalidConfigurationError(\n path + \" must be finite.\"\n );\n }\n return value;\n}\n\nfunction requireNonNegativeFinite(\n value: unknown,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed < 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than or equal to zero.\"\n );\n }\n return parsed;\n}\n\nfunction requirePositiveFinite(\n value: unknown,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (parsed <= 0) {\n throw new InvalidConfigurationError(\n path +\n \" must be greater than zero.\"\n );\n }\n return parsed;\n}\n\nfunction requireFraction(\n value: unknown,\n path: string\n): number {\n const parsed =\n requireFinite(value, path);\n if (\n parsed < 0 ||\n parsed > 1\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must lie from zero through one.\"\n );\n }\n return parsed;\n}\n\nfunction parseLimitations(\n value: unknown,\n path: string\n): readonly string[] {\n if (!Array.isArray(value)) {\n throw new InvalidConfigurationError(\n path + \" must be an array.\"\n );\n }\n const parsed =\n value.map((entry, index) =>\n requireNonEmptyString(\n entry,\n path +\n \"[\" +\n index +\n \"]\"\n )\n );\n if (\n new Set(parsed).size !==\n parsed.length\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must not contain duplicates.\"\n );\n }\n return parsed;\n}\n\nfunction parseFractionFact(\n value: unknown,\n path: string\n): EvidenceBackedFact<number> {\n const record =\n requireRecord(value, path, [\"value\", \"evidence\"]);\n return {\n value:\n requireFraction(\n record.value,\n path + \".value\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n}\n\nfunction parseNonNegativeFact(\n value: unknown,\n path: string\n): EvidenceBackedFact<number> {\n const record =\n requireRecord(value, path, [\"value\", \"evidence\"]);\n return {\n value:\n requireNonNegativeFinite(\n record.value,\n path + \".value\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n}\n\nfunction parsePositiveFact(\n value: unknown,\n path: string\n): EvidenceBackedFact<number> {\n const record =\n requireRecord(value, path, [\"value\", \"evidence\"]);\n return {\n value:\n requirePositiveFinite(\n record.value,\n path + \".value\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n}\n\nfunction parseAxis(\n value: unknown,\n path: string\n): StabilizationRotationAxis {\n if (\n typeof value !== \"string\" ||\n !AXES.has(\n value as\n StabilizationRotationAxis\n )\n ) {\n throw new InvalidConfigurationError(\n path + \" is invalid.\"\n );\n }\n return value as\n StabilizationRotationAxis;\n}\n\nfunction parseAxisResponse(\n value: unknown,\n path: string\n): StabilizationAxisResponseProfile {\n const record =\n requireRecord(value, path, [\"axis\", \"correctionGain\", \"latencySeconds\", \"maximumCorrectionAngleRad\"]);\n return {\n axis:\n parseAxis(\n record.axis,\n path + \".axis\"\n ),\n correctionGain:\n parseFractionFact(\n record.correctionGain,\n path +\n \".correctionGain\"\n ),\n latencySeconds:\n parseNonNegativeFact(\n record.latencySeconds,\n path +\n \".latencySeconds\"\n ),\n maximumCorrectionAngleRad:\n parsePositiveFact(\n record\n .maximumCorrectionAngleRad,\n path +\n \".maximumCorrectionAngleRad\"\n )\n };\n}\n\nfunction parsePanningPolicy(\n value: unknown,\n path: string\n): StabilizationPanningPolicy {\n const record =\n requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", { none: [\"kind\"], \"declared-axis-bypass\": [\"kind\", \"axis\", \"evidence\"] }, path);\n if (record.kind === \"none\") {\n return {\n kind: \"none\"\n };\n }\n if (\n record.kind ===\n \"declared-axis-bypass\"\n ) {\n return {\n kind:\n \"declared-axis-bypass\",\n axis:\n parseAxis(\n record.axis,\n path + \".axis\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseCoordinatedAllocation(\n value: unknown,\n path: string\n): StabilizationCoordinatedAllocation {\n const record =\n requireRecord(value, path, [\"totalCorrectionAppliedOnce\", \"bodyFraction\", \"lensFraction\", \"evidence\"]);\n if (\n record\n .totalCorrectionAppliedOnce !==\n true\n ) {\n throw new InvalidConfigurationError(\n path +\n \".totalCorrectionAppliedOnce must be true.\"\n );\n }\n const bodyFraction =\n requireFraction(\n record.bodyFraction,\n path + \".bodyFraction\"\n );\n const lensFraction =\n requireFraction(\n record.lensFraction,\n path + \".lensFraction\"\n );\n if (\n Math.abs(\n bodyFraction +\n lensFraction -\n 1\n ) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" bodyFraction + lensFraction must equal one.\"\n );\n }\n return {\n bodyFraction,\n lensFraction,\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n ),\n totalCorrectionAppliedOnce:\n true\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns StabilizationSystemProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseStabilizationSystemProfile(\n value: unknown\n): StabilizationSystemProfile {\n const record =\n requireRecord(\n value,\n \"stabilizationSystemProfile\", [\"schemaVersion\", \"profileKind\", \"scientificStatus\", \"architecture\", \"captureKind\", \"axisResponses\", \"panningPolicy\", \"coordinatedAllocation\", \"profileId\", \"profileVersion\", \"evidence\", \"limitations\", \"controlTransientModeled\", \"spontaneousDriftModeled\", \"cameraTranslationCorrectionModeled\", \"digitalStabilizationIncluded\", \"supportPolicyIncluded\", \"stopRatingUsedAsDynamicResponse\"]\n );\n if (\n record.schemaVersion !==\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'stabilizationSystemProfile.schemaVersion must be \"' +\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.profileKind !==\n \"generic-synthetic\" ||\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'stabilizationSystemProfile schema 0.1.0 requires profileKind \"generic-synthetic\" and scientificStatus \"approximation\".'\n );\n }\n if (\n typeof record.architecture !==\n \"string\" ||\n !ARCHITECTURES.has(\n record.architecture as\n PhysicalStabilizationArchitecture\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.architecture is invalid.\"\n );\n }\n if (\n typeof record.captureKind !==\n \"string\" ||\n !CAPTURE_KINDS.has(\n record.captureKind as\n StabilizationCaptureKind\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.captureKind is invalid.\"\n );\n }\n\n for (\n const key of [\n \"controlTransientModeled\",\n \"spontaneousDriftModeled\",\n \"cameraTranslationCorrectionModeled\",\n \"digitalStabilizationIncluded\",\n \"supportPolicyIncluded\",\n \"stopRatingUsedAsDynamicResponse\"\n ] as const\n ) {\n if (record[key] !== false) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n if (\n !Array.isArray(\n record.axisResponses\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.axisResponses must be an array.\"\n );\n }\n const axisResponses =\n record.axisResponses.map(\n (entry, index) =>\n parseAxisResponse(\n entry,\n \"stabilizationSystemProfile.axisResponses[\" +\n index +\n \"]\"\n )\n );\n const axes =\n axisResponses.map(\n (entry) =>\n entry.axis\n );\n if (\n new Set(axes).size !==\n axes.length\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.axisResponses must not contain duplicate axes.\"\n );\n }\n\n const architecture =\n record.architecture as\n PhysicalStabilizationArchitecture;\n if (\n architecture === \"off\" &&\n axisResponses.length !== 0\n ) {\n throw new InvalidConfigurationError(\n \"An off stabilization profile must not declare axis responses.\"\n );\n }\n if (\n architecture !== \"off\" &&\n axisResponses.length === 0\n ) {\n throw new InvalidConfigurationError(\n \"An enabled physical stabilization profile must declare at least one axis response.\"\n );\n }\n\n const panningPolicy =\n parsePanningPolicy(\n record.panningPolicy,\n \"stabilizationSystemProfile.panningPolicy\"\n );\n if (\n architecture === \"off\" &&\n panningPolicy.kind !== \"none\"\n ) {\n throw new InvalidConfigurationError(\n \"An off stabilization profile must use panningPolicy.kind \\\"none\\\".\"\n );\n }\n if (\n panningPolicy.kind ===\n \"declared-axis-bypass\" &&\n !axisResponses.some(\n (entry) =>\n entry.axis ===\n panningPolicy.axis\n )\n ) {\n throw new InvalidConfigurationError(\n \"Declared panning bypass axis must exist in axisResponses.\"\n );\n }\n\n const coordinatedAllocation =\n record.coordinatedAllocation ===\n undefined\n ? undefined\n : parseCoordinatedAllocation(\n record.coordinatedAllocation,\n \"stabilizationSystemProfile.coordinatedAllocation\"\n );\n if (\n architecture ===\n \"coordinated-physical\" &&\n coordinatedAllocation ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Coordinated physical stabilization requires an explicit body/lens correction allocation.\"\n );\n }\n if (\n architecture !==\n \"coordinated-physical\" &&\n coordinatedAllocation !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Only coordinated physical stabilization may declare coordinatedAllocation.\"\n );\n }\n\n return {\n schemaVersion:\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"stabilizationSystemProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"stabilizationSystemProfile.profileVersion\"\n ),\n profileKind:\n \"generic-synthetic\",\n scientificStatus:\n \"approximation\",\n architecture,\n captureKind:\n record.captureKind as\n StabilizationCaptureKind,\n axisResponses,\n panningPolicy,\n ...(coordinatedAllocation ===\n undefined\n ? {}\n : {\n coordinatedAllocation\n }),\n controlTransientModeled:\n false,\n spontaneousDriftModeled:\n false,\n cameraTranslationCorrectionModeled:\n false,\n digitalStabilizationIncluded:\n false,\n supportPolicyIncluded:\n false,\n stopRatingUsedAsDynamicResponse:\n false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"stabilizationSystemProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"stabilizationSystemProfile.limitations\"\n )\n };\n}\n\nfunction parseAngularState(\n value: unknown,\n path: string\n): StabilizationAngularStateRad {\n const record =\n requireRecord(value, path, [\"pitch\", \"yaw\", \"roll\"]);\n return {\n pitch:\n requireFinite(\n record.pitch,\n path + \".pitch\"\n ),\n yaw:\n requireFinite(\n record.yaw,\n path + \".yaw\"\n ),\n roll:\n requireFinite(\n record.roll,\n path + \".roll\"\n )\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns StabilizationDisturbanceTrajectory. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseStabilizationDisturbanceTrajectory(\n value: unknown\n): StabilizationDisturbanceTrajectory {\n const record =\n requireRecord(\n value,\n \"stabilizationDisturbanceTrajectory\", [\"version\", \"timeReference\", \"initialAngularDisplacementIsZero\", \"cameraTranslationIncluded\", \"subjectMotionIncluded\", \"supportStateEncoded\", \"samples\", \"trajectoryId\", \"evidence\", \"limitations\"]\n );\n if (\n record.version !==\n STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION ||\n record.timeReference !==\n \"first-opening-boundary-phase\" ||\n record\n .initialAngularDisplacementIsZero !==\n true ||\n record\n .cameraTranslationIncluded !==\n false ||\n record.subjectMotionIncluded !==\n false ||\n record.supportStateEncoded !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory metadata is invalid for version 0.1.0.\"\n );\n }\n if (\n !Array.isArray(record.samples) ||\n record.samples.length < 2\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory.samples must contain at least two samples.\"\n );\n }\n\n let previousTime =\n Number.NEGATIVE_INFINITY;\n const samples =\n record.samples.map(\n (entry, index) => {\n const path =\n \"stabilizationDisturbanceTrajectory.samples[\" +\n index +\n \"]\";\n const sample =\n requireRecord(\n entry,\n path, [\"timeSecondsFromCaptureReference\", \"angularDisplacementRad\"]\n );\n const time =\n requireNonNegativeFinite(\n sample\n .timeSecondsFromCaptureReference,\n path +\n \".timeSecondsFromCaptureReference\"\n );\n if (time <= previousTime) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory sample times must be strictly increasing.\"\n );\n }\n previousTime = time;\n return {\n timeSecondsFromCaptureReference:\n time,\n angularDisplacementRad:\n parseAngularState(\n sample\n .angularDisplacementRad,\n path +\n \".angularDisplacementRad\"\n )\n };\n }\n );\n\n const first =\n samples[0]!;\n if (\n first\n .timeSecondsFromCaptureReference !==\n 0 ||\n first\n .angularDisplacementRad\n .pitch !== 0 ||\n first\n .angularDisplacementRad\n .yaw !== 0 ||\n first\n .angularDisplacementRad\n .roll !== 0\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory must begin at capture-reference t=0 with zero angular displacement.\"\n );\n }\n\n return {\n version:\n STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION,\n trajectoryId:\n requireNonEmptyString(\n record.trajectoryId,\n \"stabilizationDisturbanceTrajectory.trajectoryId\"\n ),\n timeReference:\n \"first-opening-boundary-phase\",\n samples,\n initialAngularDisplacementIsZero:\n true,\n cameraTranslationIncluded:\n false,\n subjectMotionIncluded:\n false,\n supportStateEncoded:\n false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"stabilizationDisturbanceTrajectory.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"stabilizationDisturbanceTrajectory.limitations\"\n )\n };\n}\n\n/**\n * Lookup index over a parsed disturbance trajectory, built for evaluation. Support times are copied\n * once into a Float64Array (exact IEEE-754 values). Each lookup is then an O(log n) binary search\n * instead of an O(n) scan. The interpolation arithmetic is unchanged.\n */\ninterface DisturbanceIndex {\n readonly samples:\n StabilizationDisturbanceTrajectory[\"samples\"];\n readonly times: Float64Array;\n}\n\nfunction indexDisturbance(\n trajectory:\n StabilizationDisturbanceTrajectory\n): DisturbanceIndex {\n const times =\n new Float64Array(\n trajectory.samples.length\n );\n for (\n let index = 0;\n index < times.length;\n index += 1\n ) {\n times[index] =\n trajectory.samples[index]!\n .timeSecondsFromCaptureReference;\n }\n return {\n samples:\n trajectory.samples,\n times\n };\n}\n\n/**\n * Returns the left index of the support segment used for `timeSeconds`. Returns -1 for the final support\n * time, which uses its stored value. The chosen segment is exactly the one a first-match linear scan\n * would pick: the smallest `i` with `t[i] <= timeSeconds <= t[i + 1]`. Support times strictly\n * increase, so a time that equals an interior support time uses the segment on its left.\n */\nfunction locateDisturbanceSegment(\n disturbance: DisturbanceIndex,\n timeSeconds: number\n): number {\n const times =\n disturbance.times;\n const lastIndex =\n times.length - 1;\n if (\n timeSeconds < times[0]! ||\n timeSeconds > times[lastIndex]!\n ) {\n throw new InvalidScientificInputError(\n \"Requested stabilization evaluation time lies outside the disturbance trajectory support.\"\n );\n }\n\n if (\n timeSeconds ===\n times[lastIndex]!\n ) {\n return -1;\n }\n\n // Lower bound: first index whose support time is >= timeSeconds.\n let low = 0;\n let high = lastIndex;\n while (low < high) {\n const middle =\n (low + high) >>> 1;\n if (\n times[middle]! >=\n timeSeconds\n ) {\n high = middle;\n } else {\n low = middle + 1;\n }\n }\n const index =\n low === 0 ? 0 : low - 1;\n if (\n !(\n timeSeconds >=\n times[index]! &&\n timeSeconds <=\n times[index + 1]!\n )\n ) {\n throw new InvalidScientificInputError(\n \"Disturbance trajectory interpolation failed.\"\n );\n }\n return index;\n}\n\nfunction interpolateDisturbanceSegment(\n disturbance: DisturbanceIndex,\n segmentIndex: number,\n timeSeconds: number,\n axis:\n StabilizationRotationAxis\n): number {\n const samples =\n disturbance.samples;\n if (segmentIndex < 0) {\n return samples[\n samples.length - 1\n ]!\n .angularDisplacementRad[\n axis\n ];\n }\n const left =\n samples[segmentIndex]!;\n const right =\n samples[\n segmentIndex + 1\n ]!;\n const duration =\n right\n .timeSecondsFromCaptureReference -\n left\n .timeSecondsFromCaptureReference;\n const phase =\n duration === 0\n ? 0\n : (\n timeSeconds -\n left\n .timeSecondsFromCaptureReference\n ) /\n duration;\n const a =\n left\n .angularDisplacementRad[\n axis\n ];\n const b =\n right\n .angularDisplacementRad[\n axis\n ];\n return (\n a +\n (b - a) * phase\n );\n}\n\nfunction interpolateAxis(\n disturbance: DisturbanceIndex,\n timeSeconds: number,\n axis:\n StabilizationRotationAxis\n): number {\n return interpolateDisturbanceSegment(\n disturbance,\n locateDisturbanceSegment(\n disturbance,\n timeSeconds\n ),\n timeSeconds,\n axis\n );\n}\n\nfunction axisValue(\n state:\n StabilizationAngularStateRad,\n axis:\n StabilizationRotationAxis\n): number {\n return state[axis];\n}\n\nfunction setAxisValue(\n state:\n StabilizationAngularStateRad,\n axis:\n StabilizationRotationAxis,\n value: number\n): void {\n state[axis] = value;\n}\n\nfunction clampSymmetric(\n value: number,\n limit: number\n): number {\n return Math.max(\n -limit,\n Math.min(limit, value)\n );\n}\n\ntype AxisResponseIndex = ReadonlyMap<\n StabilizationRotationAxis,\n StabilizationSystemProfile[\"axisResponses\"][number]\n>;\n\n/** Built once per calculation. Later entries win, as with a per-evaluation Map. */\nfunction indexAxisResponses(\n profile:\n StabilizationSystemProfile\n): AxisResponseIndex {\n return new Map(\n profile.axisResponses.map(\n (response) => [\n response.axis,\n response\n ] as const\n )\n );\n}\n\nfunction evaluateAtTime(\n disturbance: DisturbanceIndex,\n profile:\n StabilizationSystemProfile,\n responses: AxisResponseIndex,\n timeSeconds: number\n): StabilizedRotationSample {\n // One segment lookup serves all three axes at the same time.\n const segment =\n locateDisturbanceSegment(\n disturbance,\n timeSeconds\n );\n const current:\n StabilizationAngularStateRad = {\n pitch:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"pitch\"\n ),\n yaw:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"yaw\"\n ),\n roll:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"roll\"\n )\n };\n const correction:\n StabilizationAngularStateRad = {\n pitch: 0,\n yaw: 0,\n roll: 0\n };\n const residual:\n StabilizationAngularStateRad = {\n ...current\n };\n\n const axes =\n [\"pitch\", \"yaw\", \"roll\"] as const;\n const resolvedAxes =\n axes.map((axis) => {\n const response =\n responses.get(axis);\n const bypassed =\n profile.panningPolicy.kind ===\n \"declared-axis-bypass\" &&\n profile.panningPolicy.axis ===\n axis;\n\n if (\n profile.architecture ===\n \"off\" ||\n response === undefined ||\n bypassed\n ) {\n return {\n axis,\n disturbanceAngleRad:\n axisValue(\n current,\n axis\n ),\n delayedMeasuredAngleRad:\n 0,\n requestedCorrectionAngleRad:\n 0,\n appliedCorrectionAngleRad:\n 0,\n residualAngleRad:\n axisValue(\n current,\n axis\n ),\n correctionGain:\n response?.correctionGain\n .value ?? 0,\n latencySeconds:\n response?.latencySeconds\n .value ?? 0,\n maximumCorrectionAngleRad:\n response\n ?.maximumCorrectionAngleRad\n .value ?? 0,\n bypassedForDeclaredPan:\n bypassed,\n correctionLimitReached:\n false\n };\n }\n\n const delayedTime =\n timeSeconds -\n response\n .latencySeconds.value;\n const delayedMeasured =\n delayedTime < 0\n ? 0\n : interpolateAxis(\n disturbance,\n delayedTime,\n axis\n );\n const requested =\n delayedMeasured *\n response\n .correctionGain.value;\n const applied =\n clampSymmetric(\n requested,\n response\n .maximumCorrectionAngleRad\n .value\n );\n const residualAngle =\n axisValue(\n current,\n axis\n ) -\n applied;\n\n setAxisValue(\n correction,\n axis,\n applied\n );\n setAxisValue(\n residual,\n axis,\n residualAngle\n );\n\n return {\n axis,\n disturbanceAngleRad:\n axisValue(\n current,\n axis\n ),\n delayedMeasuredAngleRad:\n delayedMeasured,\n requestedCorrectionAngleRad:\n requested,\n appliedCorrectionAngleRad:\n applied,\n residualAngleRad:\n residualAngle,\n correctionGain:\n response\n .correctionGain.value,\n latencySeconds:\n response\n .latencySeconds.value,\n maximumCorrectionAngleRad:\n response\n .maximumCorrectionAngleRad\n .value,\n bypassedForDeclaredPan:\n false,\n correctionLimitReached:\n applied !== requested\n };\n });\n\n return {\n timeSecondsFromCaptureReference:\n timeSeconds,\n disturbanceAngularDisplacementRad:\n current,\n appliedCorrectionAngularDisplacementRad:\n correction,\n residualAngularDisplacementRad:\n residual,\n axes:\n resolvedAxes\n };\n}\n\n/**\n * Runs the declared generic per-axis controller against an explicit angular disturbance trajectory.\n * Returns the residual motion, with diagnostics for latency and travel limits.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param input - CalculateStabilizedRotationTrajectoryInput. See that type for coordinates, units and profile binding.\n * @returns CalculationResult<StabilizedRotationTrajectory>. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function calculateStabilizedRotationTrajectory(\n input:\n CalculateStabilizedRotationTrajectoryInput\n): CalculationResult<StabilizedRotationTrajectory> {\n requireInputKeys(input, \"calculateStabilizedRotationTrajectory\", [\"disturbance\", \"profile\", \"captureKind\"]);\n const disturbance =\n parseStabilizationDisturbanceTrajectory(\n input.disturbance\n );\n const profile =\n parseStabilizationSystemProfile(\n input.profile\n );\n\n if (\n input.captureKind !==\n profile.captureKind\n ) {\n throw new InvalidScientificInputError(\n \"captureKind must exactly match the stabilization profile captureKind.\"\n );\n }\n\n const disturbanceIndex =\n indexDisturbance(disturbance);\n const responses =\n indexAxisResponses(profile);\n const samples =\n disturbance.samples.map(\n (sample) =>\n evaluateAtTime(\n disturbanceIndex,\n profile,\n responses,\n sample\n .timeSecondsFromCaptureReference\n )\n );\n\n return approximationResult(\n {\n profileId:\n profile.profileId,\n profileVersion:\n profile.profileVersion,\n trajectoryId:\n disturbance.trajectoryId,\n architecture:\n profile.architecture,\n captureKind:\n input.captureKind,\n timeReference:\n \"first-opening-boundary-phase\",\n samples,\n correctionModel:\n \"delayed-linear-image-equivalent-angular-response\",\n supportStateConsumed:\n false,\n translationCorrectionModeled:\n false,\n digitalStabilizationApplied:\n false,\n digitalStabilizationOwnedBy:\n \"downstream-geometric-correction-composition\",\n coordinatedCorrectionDoubleCounted:\n false,\n zeroDisturbanceCanCreateMotion:\n false\n },\n \"generic-time-domain-physical-stabilization\",\n \"1.0.0\",\n [\n \"The stabilization response is a generic synthetic image-equivalent rotational correction, not a manufacturer-specific IBIS/OIS calibration.\",\n \"Correction uses explicit per-axis gain, latency and symmetric angular correction limits.\",\n \"A coordinated profile allocates one total correction between body and lens for descriptive ownership only; the total correction is applied once.\",\n \"Support state is not an input and never silently toggles stabilization.\",\n \"Declared panning bypass suppresses correction only on the explicitly selected axis; pan intent is never inferred.\",\n \"Camera translation/parallax correction is not modeled because translational image motion depends on scene depth.\",\n \"Digital stabilization is a separate downstream geometric/crop/resampling domain.\",\n \"CIPA-style stop ratings are not used as a dynamic response function.\",\n \"The legacy stabilizationStopsEquivalent approximation remains unchanged.\"\n ]\n );\n}\n\ntype ExposureWindowSample =\n ResolvedCaptureModeTiming[\"exposureWindows\"][\"samples\"][number];\ntype ExposureWindowIndex = ReadonlyMap<\n unknown,\n ReadonlyMap<unknown, readonly ExposureWindowSample[]>\n>;\n\n/**\n * Groups the committed exposure-window samples by native point, once per calculation, and keeps their\n * order. Map keys compare with SameValueZero, so lookups are filtered again with the original `===`\n * test: NaN never matches, and +0 matches -0.\n */\nfunction indexExposureWindows(\n timing:\n ResolvedCaptureModeTiming\n): ExposureWindowIndex {\n requireInputObject(timing, \"timing\");\n requireInputObject(timing.exposureWindows, \"timing.exposureWindows\");\n if (!Array.isArray(timing.exposureWindows.samples)) throw new InvalidConfigurationError(\"timing.exposureWindows.samples must be an array.\");\n timing.exposureWindows.samples.forEach((sample, index) => {\n requireInputObject(sample, \"timing.exposureWindows.samples[\" + index + \"]\");\n requireInputObject(sample.pointNative, \"timing.exposureWindows.samples[\" + index + \"].pointNative\");\n });\n const byX =\n new Map<\n unknown,\n Map<unknown, ExposureWindowSample[]>\n >();\n for (const sample of timing.exposureWindows.samples) {\n let byY =\n byX.get(sample.pointNative.x);\n if (byY === undefined) {\n byY = new Map();\n byX.set(\n sample.pointNative.x,\n byY\n );\n }\n const bucket =\n byY.get(sample.pointNative.y);\n if (bucket === undefined) {\n byY.set(\n sample.pointNative.y,\n [sample]\n );\n } else {\n bucket.push(sample);\n }\n }\n return byX;\n}\n\nfunction localExposureForPoint(\n windows: ExposureWindowIndex,\n point:\n RasterPoint\n): {\n start: number;\n end: number;\n duration: number;\n} {\n const matches =\n (\n windows\n .get(point.x)\n ?.get(point.y) ?? []\n ).filter(\n (sample) =>\n sample.pointNative.x ===\n point.x &&\n sample.pointNative.y ===\n point.y\n );\n if (matches.length !== 1) {\n throw new InvalidScientificInputError(\n \"Each stabilization sample point must match exactly one committed exposure-window sample point.\"\n );\n }\n const match =\n matches[0]!;\n return {\n start:\n match\n .startOffsetSecondsFromOpeningReference,\n end:\n match\n .endOffsetSecondsFromOpeningReference,\n duration:\n match\n .localExposureDurationSeconds\n };\n}\n\n/**\n * Feeds the residual stabilized rotation into the existing local-exposure temporal mapping. Shutter\n * timing is not changed, and no blur radius is invented.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param input - CalculateStabilizedCaptureTemporalSamplesInput. See that type for coordinates, units and profile binding.\n * @returns CalculationResult<StabilizedCaptureTemporalSamples>. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function calculateStabilizedCaptureTemporalSamples(\n input:\n CalculateStabilizedCaptureTemporalSamplesInput\n): CalculationResult<StabilizedCaptureTemporalSamples> {\n requireInputKeys(input, \"calculateStabilizedCaptureTemporalSamples\", [\"disturbance\", \"profile\", \"captureKind\", \"timing\", \"samplePointsNative\", \"temporalSampleCount\"]);\n requireInputObject(input.timing, \"timing\");\n const disturbance =\n parseStabilizationDisturbanceTrajectory(\n input.disturbance\n );\n const profile =\n parseStabilizationSystemProfile(\n input.profile\n );\n if (\n input.captureKind !==\n profile.captureKind\n ) {\n throw new InvalidScientificInputError(\n \"captureKind must exactly match the stabilization profile captureKind.\"\n );\n }\n requirePositiveInteger(\n \"temporalSampleCount\",\n input.temporalSampleCount\n );\n if (\n !Array.isArray(\n input.samplePointsNative\n ) ||\n input.samplePointsNative.length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"samplePointsNative must be a non-empty array.\"\n );\n }\n input.samplePointsNative.forEach((point, index) => requireInputObject(point, \"samplePointsNative[\" + index + \"]\"));\n\n const totalNodeCount =\n input.temporalSampleCount *\n input.samplePointsNative.length;\n if (\n !Number.isSafeInteger(\n totalNodeCount\n )\n ) {\n throw new InvalidScientificInputError(\n \"temporalSampleCount × samplePointsNative.length must remain a safe integer.\"\n );\n }\n\n const disturbanceIndex =\n indexDisturbance(disturbance);\n const responses =\n indexAxisResponses(profile);\n let exposureWindowIndex:\n ExposureWindowIndex | undefined;\n const points =\n input.samplePointsNative.map(\n (point) => {\n exposureWindowIndex ??=\n indexExposureWindows(\n input.timing\n );\n const exposure =\n localExposureForPoint(\n exposureWindowIndex,\n point\n );\n const normalizedTimeWeight =\n 1 /\n input.temporalSampleCount;\n const timeMeasureSeconds =\n exposure.duration /\n input.temporalSampleCount;\n\n const nodes =\n Array.from(\n {\n length:\n input.temporalSampleCount\n },\n (\n _,\n temporalSampleIndex\n ) => {\n const localExposurePhase =\n (\n temporalSampleIndex +\n 0.5\n ) /\n input.temporalSampleCount;\n const captureTime =\n exposure.start +\n localExposurePhase *\n exposure.duration;\n return {\n temporalSampleIndex,\n localExposurePhase,\n captureTimeSecondsFromReference:\n captureTime,\n normalizedTimeWeight,\n timeMeasureSeconds,\n stabilization:\n evaluateAtTime(\n disturbanceIndex,\n profile,\n responses,\n captureTime\n )\n };\n }\n );\n\n return {\n destinationPointNative: {\n ...point\n },\n localExposureWindow: {\n startSecondsFromCaptureReference:\n exposure.start,\n endSecondsFromCaptureReference:\n exposure.end,\n durationSeconds:\n exposure.duration\n },\n nodes\n };\n }\n );\n\n return approximationResult(\n {\n profileId:\n profile.profileId,\n trajectoryId:\n disturbance.trajectoryId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n captureKind:\n input.captureKind,\n architecture:\n profile.architecture,\n timeReference:\n \"first-opening-boundary-phase\",\n quadratureScheme:\n \"uniform-midpoint\",\n temporalSampleCount:\n input.temporalSampleCount,\n points,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n supportStateConsumed:\n false,\n translationCorrectionModeled:\n false,\n digitalStabilizationApplied:\n false\n },\n \"capture-local-stabilization-temporal-sampling\",\n \"1.0.0\",\n [\n \"Stabilization is evaluated at deterministic midpoint nodes inside each authoritative local exposure window of the exposure-window model.\",\n \"Sensor data-readout timing is not substituted for exposure timing.\",\n \"The result is rotational disturbance/correction/residual state only; it does not itself calculate image-plane mapping, radiance, blur, PSF or output pixels.\",\n \"Translation/parallax, subject motion, shutter shock, support vibration sources and digital stabilization remain separate domains.\"\n ]\n );\n}\n"]}
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/stabilization/system.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Generic image stabilization: profiles, disturbance trajectories, the stabilized rotation and its\n * effect on capture timing samples.\n *\n * The parsers validate untrusted input and return the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @see docs/STABILIZATION.md for the equations, units, coordinate conventions, known blockers and\n * support limits.\n */\n\nimport {\n approximationResult,\n type CalculationResult\n} from \"../core/calculation-result.js\";\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceBackedFact,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport {\n InvalidScientificInputError,\n requirePositiveInteger\n} from \"../core/validation.js\";\nimport type {\n RasterPoint\n} from \"../output/capture-geometry.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputKeys, requireInputObject, rejectUnknownVariantFields, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireConfigFinite as requireFinite, parseConfigLimitations as parseLimitations, requireConfigFiniteAtLeastZero as requireNonNegativeFinite, requireConfigUnitInterval as requireFraction } from \"../core/record-validation.js\";\nimport { parseNonNegativeFact, parsePositiveFact } from \"../sensor/raw-readout.js\";\n\nexport const STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION =\n \"0.1.0\" as const;\n\nexport type StabilizationRotationAxis =\n | \"pitch\"\n | \"yaw\"\n | \"roll\";\n\nexport type PhysicalStabilizationArchitecture =\n | \"off\"\n | \"sensor-shift\"\n | \"lens-optical\"\n | \"coordinated-physical\";\n\nexport type StabilizationCaptureKind =\n | \"still\"\n | \"video\";\n\nexport interface StabilizationAngularStateRad {\n pitch: number;\n yaw: number;\n roll: number;\n}\n\nexport interface StabilizationDisturbanceSample {\n timeSecondsFromCaptureReference:\n number;\n angularDisplacementRad:\n StabilizationAngularStateRad;\n}\n\nexport interface StabilizationDisturbanceTrajectory {\n version:\n typeof STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION;\n trajectoryId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n samples:\n readonly StabilizationDisturbanceSample[];\n initialAngularDisplacementIsZero:\n true;\n cameraTranslationIncluded:\n false;\n subjectMotionIncluded:\n false;\n supportStateEncoded:\n false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface StabilizationAxisResponseProfile {\n axis: StabilizationRotationAxis;\n correctionGain:\n EvidenceBackedFact<number>;\n latencySeconds:\n EvidenceBackedFact<number>;\n maximumCorrectionAngleRad:\n EvidenceBackedFact<number>;\n}\n\nexport type StabilizationPanningPolicy =\n | {\n kind: \"none\";\n }\n | {\n kind:\n \"declared-axis-bypass\";\n axis:\n StabilizationRotationAxis;\n evidence:\n readonly EvidenceProvenance[];\n };\n\nexport interface StabilizationCoordinatedAllocation {\n bodyFraction: number;\n lensFraction: number;\n evidence: readonly EvidenceProvenance[];\n totalCorrectionAppliedOnce:\n true;\n}\n\nexport interface StabilizationSystemProfile {\n schemaVersion:\n typeof STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n profileKind:\n \"generic-synthetic\";\n scientificStatus:\n \"approximation\";\n architecture:\n PhysicalStabilizationArchitecture;\n captureKind:\n StabilizationCaptureKind;\n axisResponses:\n readonly StabilizationAxisResponseProfile[];\n panningPolicy:\n StabilizationPanningPolicy;\n coordinatedAllocation?:\n StabilizationCoordinatedAllocation;\n controlTransientModeled: false;\n spontaneousDriftModeled: false;\n cameraTranslationCorrectionModeled:\n false;\n digitalStabilizationIncluded:\n false;\n supportPolicyIncluded: false;\n stopRatingUsedAsDynamicResponse:\n false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface CalculateStabilizedRotationTrajectoryInput {\n disturbance:\n StabilizationDisturbanceTrajectory;\n profile:\n StabilizationSystemProfile;\n captureKind:\n StabilizationCaptureKind;\n}\n\nexport interface StabilizationAxisResolution {\n axis: StabilizationRotationAxis;\n disturbanceAngleRad: number;\n delayedMeasuredAngleRad: number;\n requestedCorrectionAngleRad:\n number;\n appliedCorrectionAngleRad:\n number;\n residualAngleRad: number;\n correctionGain: number;\n latencySeconds: number;\n maximumCorrectionAngleRad:\n number;\n bypassedForDeclaredPan:\n boolean;\n correctionLimitReached:\n boolean;\n}\n\nexport interface StabilizedRotationSample {\n timeSecondsFromCaptureReference:\n number;\n disturbanceAngularDisplacementRad:\n StabilizationAngularStateRad;\n appliedCorrectionAngularDisplacementRad:\n StabilizationAngularStateRad;\n residualAngularDisplacementRad:\n StabilizationAngularStateRad;\n axes:\n readonly StabilizationAxisResolution[];\n}\n\nexport interface StabilizedRotationTrajectory {\n profileId: string;\n profileVersion: string;\n trajectoryId: string;\n architecture:\n PhysicalStabilizationArchitecture;\n captureKind:\n StabilizationCaptureKind;\n timeReference:\n \"first-opening-boundary-phase\";\n samples:\n readonly StabilizedRotationSample[];\n correctionModel:\n \"delayed-linear-image-equivalent-angular-response\";\n supportStateConsumed: false;\n translationCorrectionModeled:\n false;\n digitalStabilizationApplied:\n false;\n digitalStabilizationOwnedBy:\n \"downstream-geometric-correction-composition\";\n coordinatedCorrectionDoubleCounted:\n false;\n zeroDisturbanceCanCreateMotion:\n false;\n}\n\nexport interface CalculateStabilizedCaptureTemporalSamplesInput {\n disturbance:\n StabilizationDisturbanceTrajectory;\n profile:\n StabilizationSystemProfile;\n captureKind:\n StabilizationCaptureKind;\n timing:\n ResolvedCaptureModeTiming;\n samplePointsNative:\n readonly RasterPoint[];\n temporalSampleCount: number;\n}\n\nexport interface StabilizedCaptureTemporalNode {\n temporalSampleIndex: number;\n localExposurePhase: number;\n captureTimeSecondsFromReference:\n number;\n normalizedTimeWeight: number;\n timeMeasureSeconds: number;\n stabilization:\n StabilizedRotationSample;\n}\n\nexport interface StabilizedCaptureTemporalPoint {\n destinationPointNative:\n RasterPoint;\n localExposureWindow: {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n nodes:\n readonly StabilizedCaptureTemporalNode[];\n}\n\nexport interface StabilizedCaptureTemporalSamples {\n profileId: string;\n trajectoryId: string;\n captureModeId: string;\n timingProfileId: string;\n captureKind:\n StabilizationCaptureKind;\n architecture:\n PhysicalStabilizationArchitecture;\n timeReference:\n \"first-opening-boundary-phase\";\n quadratureScheme:\n \"uniform-midpoint\";\n temporalSampleCount: number;\n points:\n readonly StabilizedCaptureTemporalPoint[];\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n supportStateConsumed: false;\n translationCorrectionModeled:\n false;\n digitalStabilizationApplied:\n false;\n}\n\nconst AXES =\n new Set<StabilizationRotationAxis>([\n \"pitch\",\n \"yaw\",\n \"roll\"\n ]);\n\nconst ARCHITECTURES =\n new Set<PhysicalStabilizationArchitecture>([\n \"off\",\n \"sensor-shift\",\n \"lens-optical\",\n \"coordinated-physical\"\n ]);\n\nconst CAPTURE_KINDS =\n new Set<StabilizationCaptureKind>([\n \"still\",\n \"video\"\n ]);\n\nfunction parseFractionFact(\n value: unknown,\n path: string\n): EvidenceBackedFact<number> {\n const record =\n requireRecord(value, path, [\"value\", \"evidence\"]);\n return {\n value:\n requireFraction(\n record.value,\n path + \".value\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n}\n\nfunction parseAxis(\n value: unknown,\n path: string\n): StabilizationRotationAxis {\n if (\n typeof value !== \"string\" ||\n !AXES.has(\n value as\n StabilizationRotationAxis\n )\n ) {\n throw new InvalidConfigurationError(\n path + \" is invalid.\"\n );\n }\n return value as\n StabilizationRotationAxis;\n}\n\nfunction parseAxisResponse(\n value: unknown,\n path: string\n): StabilizationAxisResponseProfile {\n const record =\n requireRecord(value, path, [\"axis\", \"correctionGain\", \"latencySeconds\", \"maximumCorrectionAngleRad\"]);\n return {\n axis:\n parseAxis(\n record.axis,\n path + \".axis\"\n ),\n correctionGain:\n parseFractionFact(\n record.correctionGain,\n path +\n \".correctionGain\"\n ),\n latencySeconds:\n parseNonNegativeFact(\n record.latencySeconds,\n path +\n \".latencySeconds\"\n ),\n maximumCorrectionAngleRad:\n parsePositiveFact(\n record\n .maximumCorrectionAngleRad,\n path +\n \".maximumCorrectionAngleRad\"\n )\n };\n}\n\nfunction parsePanningPolicy(\n value: unknown,\n path: string\n): StabilizationPanningPolicy {\n const record =\n requireRecord(value, path, null);\n rejectUnknownVariantFields(record, \"kind\", { none: [\"kind\"], \"declared-axis-bypass\": [\"kind\", \"axis\", \"evidence\"] }, path);\n if (record.kind === \"none\") {\n return {\n kind: \"none\"\n };\n }\n if (\n record.kind ===\n \"declared-axis-bypass\"\n ) {\n return {\n kind:\n \"declared-axis-bypass\",\n axis:\n parseAxis(\n record.axis,\n path + \".axis\"\n ),\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n )\n };\n }\n throw new InvalidConfigurationError(\n path + \".kind is invalid.\"\n );\n}\n\nfunction parseCoordinatedAllocation(\n value: unknown,\n path: string\n): StabilizationCoordinatedAllocation {\n const record =\n requireRecord(value, path, [\"totalCorrectionAppliedOnce\", \"bodyFraction\", \"lensFraction\", \"evidence\"]);\n if (\n record\n .totalCorrectionAppliedOnce !==\n true\n ) {\n throw new InvalidConfigurationError(\n path +\n \".totalCorrectionAppliedOnce must be true.\"\n );\n }\n const bodyFraction =\n requireFraction(\n record.bodyFraction,\n path + \".bodyFraction\"\n );\n const lensFraction =\n requireFraction(\n record.lensFraction,\n path + \".lensFraction\"\n );\n if (\n Math.abs(\n bodyFraction +\n lensFraction -\n 1\n ) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" bodyFraction + lensFraction must equal one.\"\n );\n }\n return {\n bodyFraction,\n lensFraction,\n evidence:\n parseEvidenceList(\n record.evidence,\n path + \".evidence\"\n ),\n totalCorrectionAppliedOnce:\n true\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns StabilizationSystemProfile. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseStabilizationSystemProfile(\n value: unknown\n): StabilizationSystemProfile {\n const record =\n requireRecord(\n value,\n \"stabilizationSystemProfile\", [\"schemaVersion\", \"profileKind\", \"scientificStatus\", \"architecture\", \"captureKind\", \"axisResponses\", \"panningPolicy\", \"coordinatedAllocation\", \"profileId\", \"profileVersion\", \"evidence\", \"limitations\", \"controlTransientModeled\", \"spontaneousDriftModeled\", \"cameraTranslationCorrectionModeled\", \"digitalStabilizationIncluded\", \"supportPolicyIncluded\", \"stopRatingUsedAsDynamicResponse\"]\n );\n if (\n record.schemaVersion !==\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'stabilizationSystemProfile.schemaVersion must be \"' +\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.profileKind !==\n \"generic-synthetic\" ||\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'stabilizationSystemProfile schema 0.1.0 requires profileKind \"generic-synthetic\" and scientificStatus \"approximation\".'\n );\n }\n if (\n typeof record.architecture !==\n \"string\" ||\n !ARCHITECTURES.has(\n record.architecture as\n PhysicalStabilizationArchitecture\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.architecture is invalid.\"\n );\n }\n if (\n typeof record.captureKind !==\n \"string\" ||\n !CAPTURE_KINDS.has(\n record.captureKind as\n StabilizationCaptureKind\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.captureKind is invalid.\"\n );\n }\n\n for (\n const key of [\n \"controlTransientModeled\",\n \"spontaneousDriftModeled\",\n \"cameraTranslationCorrectionModeled\",\n \"digitalStabilizationIncluded\",\n \"supportPolicyIncluded\",\n \"stopRatingUsedAsDynamicResponse\"\n ] as const\n ) {\n if (record[key] !== false) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n if (\n !Array.isArray(\n record.axisResponses\n )\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.axisResponses must be an array.\"\n );\n }\n const axisResponses =\n record.axisResponses.map(\n (entry, index) =>\n parseAxisResponse(\n entry,\n \"stabilizationSystemProfile.axisResponses[\" +\n index +\n \"]\"\n )\n );\n const axes =\n axisResponses.map(\n (entry) =>\n entry.axis\n );\n if (\n new Set(axes).size !==\n axes.length\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationSystemProfile.axisResponses must not contain duplicate axes.\"\n );\n }\n\n const architecture =\n record.architecture as\n PhysicalStabilizationArchitecture;\n if (\n architecture === \"off\" &&\n axisResponses.length !== 0\n ) {\n throw new InvalidConfigurationError(\n \"An off stabilization profile must not declare axis responses.\"\n );\n }\n if (\n architecture !== \"off\" &&\n axisResponses.length === 0\n ) {\n throw new InvalidConfigurationError(\n \"An enabled physical stabilization profile must declare at least one axis response.\"\n );\n }\n\n const panningPolicy =\n parsePanningPolicy(\n record.panningPolicy,\n \"stabilizationSystemProfile.panningPolicy\"\n );\n if (\n architecture === \"off\" &&\n panningPolicy.kind !== \"none\"\n ) {\n throw new InvalidConfigurationError(\n \"An off stabilization profile must use panningPolicy.kind \\\"none\\\".\"\n );\n }\n if (\n panningPolicy.kind ===\n \"declared-axis-bypass\" &&\n !axisResponses.some(\n (entry) =>\n entry.axis ===\n panningPolicy.axis\n )\n ) {\n throw new InvalidConfigurationError(\n \"Declared panning bypass axis must exist in axisResponses.\"\n );\n }\n\n const coordinatedAllocation =\n record.coordinatedAllocation ===\n undefined\n ? undefined\n : parseCoordinatedAllocation(\n record.coordinatedAllocation,\n \"stabilizationSystemProfile.coordinatedAllocation\"\n );\n if (\n architecture ===\n \"coordinated-physical\" &&\n coordinatedAllocation ===\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Coordinated physical stabilization requires an explicit body/lens correction allocation.\"\n );\n }\n if (\n architecture !==\n \"coordinated-physical\" &&\n coordinatedAllocation !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"Only coordinated physical stabilization may declare coordinatedAllocation.\"\n );\n }\n\n return {\n schemaVersion:\n STABILIZATION_SYSTEM_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"stabilizationSystemProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"stabilizationSystemProfile.profileVersion\"\n ),\n profileKind:\n \"generic-synthetic\",\n scientificStatus:\n \"approximation\",\n architecture,\n captureKind:\n record.captureKind as\n StabilizationCaptureKind,\n axisResponses,\n panningPolicy,\n ...(coordinatedAllocation ===\n undefined\n ? {}\n : {\n coordinatedAllocation\n }),\n controlTransientModeled:\n false,\n spontaneousDriftModeled:\n false,\n cameraTranslationCorrectionModeled:\n false,\n digitalStabilizationIncluded:\n false,\n supportPolicyIncluded:\n false,\n stopRatingUsedAsDynamicResponse:\n false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"stabilizationSystemProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"stabilizationSystemProfile.limitations\"\n )\n };\n}\n\nfunction parseAngularState(\n value: unknown,\n path: string\n): StabilizationAngularStateRad {\n const record =\n requireRecord(value, path, [\"pitch\", \"yaw\", \"roll\"]);\n return {\n pitch:\n requireFinite(\n record.pitch,\n path + \".pitch\"\n ),\n yaw:\n requireFinite(\n record.yaw,\n path + \".yaw\"\n ),\n roll:\n requireFinite(\n record.roll,\n path + \".roll\"\n )\n };\n}\n\n/**\n * Validates an untrusted declaration and returns the normalized typed contract. Unknown enum values,\n * missing required fields and incompatible scientific data are rejected here.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns StabilizationDisturbanceTrajectory. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function parseStabilizationDisturbanceTrajectory(\n value: unknown\n): StabilizationDisturbanceTrajectory {\n const record =\n requireRecord(\n value,\n \"stabilizationDisturbanceTrajectory\", [\"version\", \"timeReference\", \"initialAngularDisplacementIsZero\", \"cameraTranslationIncluded\", \"subjectMotionIncluded\", \"supportStateEncoded\", \"samples\", \"trajectoryId\", \"evidence\", \"limitations\"]\n );\n if (\n record.version !==\n STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION ||\n record.timeReference !==\n \"first-opening-boundary-phase\" ||\n record\n .initialAngularDisplacementIsZero !==\n true ||\n record\n .cameraTranslationIncluded !==\n false ||\n record.subjectMotionIncluded !==\n false ||\n record.supportStateEncoded !==\n false\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory metadata is invalid for version 0.1.0.\"\n );\n }\n if (\n !Array.isArray(record.samples) ||\n record.samples.length < 2\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory.samples must contain at least two samples.\"\n );\n }\n\n let previousTime =\n Number.NEGATIVE_INFINITY;\n const samples =\n record.samples.map(\n (entry, index) => {\n const path =\n \"stabilizationDisturbanceTrajectory.samples[\" +\n index +\n \"]\";\n const sample =\n requireRecord(\n entry,\n path, [\"timeSecondsFromCaptureReference\", \"angularDisplacementRad\"]\n );\n const time =\n requireNonNegativeFinite(\n sample\n .timeSecondsFromCaptureReference,\n path +\n \".timeSecondsFromCaptureReference\"\n );\n if (time <= previousTime) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory sample times must be strictly increasing.\"\n );\n }\n previousTime = time;\n return {\n timeSecondsFromCaptureReference:\n time,\n angularDisplacementRad:\n parseAngularState(\n sample\n .angularDisplacementRad,\n path +\n \".angularDisplacementRad\"\n )\n };\n }\n );\n\n const first =\n samples[0]!;\n if (\n first\n .timeSecondsFromCaptureReference !==\n 0 ||\n first\n .angularDisplacementRad\n .pitch !== 0 ||\n first\n .angularDisplacementRad\n .yaw !== 0 ||\n first\n .angularDisplacementRad\n .roll !== 0\n ) {\n throw new InvalidConfigurationError(\n \"stabilizationDisturbanceTrajectory must begin at capture-reference t=0 with zero angular displacement.\"\n );\n }\n\n return {\n version:\n STABILIZATION_DISTURBANCE_TRAJECTORY_VERSION,\n trajectoryId:\n requireNonEmptyString(\n record.trajectoryId,\n \"stabilizationDisturbanceTrajectory.trajectoryId\"\n ),\n timeReference:\n \"first-opening-boundary-phase\",\n samples,\n initialAngularDisplacementIsZero:\n true,\n cameraTranslationIncluded:\n false,\n subjectMotionIncluded:\n false,\n supportStateEncoded:\n false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"stabilizationDisturbanceTrajectory.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"stabilizationDisturbanceTrajectory.limitations\"\n )\n };\n}\n\n/**\n * Lookup index over a parsed disturbance trajectory, built for evaluation. Support times are copied\n * once into a Float64Array (exact IEEE-754 values). Each lookup is then an O(log n) binary search\n * instead of an O(n) scan. The interpolation arithmetic is unchanged.\n */\ninterface DisturbanceIndex {\n readonly samples:\n StabilizationDisturbanceTrajectory[\"samples\"];\n readonly times: Float64Array;\n}\n\nfunction indexDisturbance(\n trajectory:\n StabilizationDisturbanceTrajectory\n): DisturbanceIndex {\n const times =\n new Float64Array(\n trajectory.samples.length\n );\n for (\n let index = 0;\n index < times.length;\n index += 1\n ) {\n times[index] =\n trajectory.samples[index]!\n .timeSecondsFromCaptureReference;\n }\n return {\n samples:\n trajectory.samples,\n times\n };\n}\n\n/**\n * Returns the left index of the support segment used for `timeSeconds`. Returns -1 for the final support\n * time, which uses its stored value. The chosen segment is exactly the one a first-match linear scan\n * would pick: the smallest `i` with `t[i] <= timeSeconds <= t[i + 1]`. Support times strictly\n * increase, so a time that equals an interior support time uses the segment on its left.\n */\nfunction locateDisturbanceSegment(\n disturbance: DisturbanceIndex,\n timeSeconds: number\n): number {\n const times =\n disturbance.times;\n const lastIndex =\n times.length - 1;\n if (\n timeSeconds < times[0]! ||\n timeSeconds > times[lastIndex]!\n ) {\n throw new InvalidScientificInputError(\n \"Requested stabilization evaluation time lies outside the disturbance trajectory support.\"\n );\n }\n\n if (\n timeSeconds ===\n times[lastIndex]!\n ) {\n return -1;\n }\n\n // Lower bound: first index whose support time is >= timeSeconds.\n let low = 0;\n let high = lastIndex;\n while (low < high) {\n const middle =\n (low + high) >>> 1;\n if (\n times[middle]! >=\n timeSeconds\n ) {\n high = middle;\n } else {\n low = middle + 1;\n }\n }\n const index =\n low === 0 ? 0 : low - 1;\n if (\n !(\n timeSeconds >=\n times[index]! &&\n timeSeconds <=\n times[index + 1]!\n )\n ) {\n throw new InvalidScientificInputError(\n \"Disturbance trajectory interpolation failed.\"\n );\n }\n return index;\n}\n\nfunction interpolateDisturbanceSegment(\n disturbance: DisturbanceIndex,\n segmentIndex: number,\n timeSeconds: number,\n axis:\n StabilizationRotationAxis\n): number {\n const samples =\n disturbance.samples;\n if (segmentIndex < 0) {\n return samples[\n samples.length - 1\n ]!\n .angularDisplacementRad[\n axis\n ];\n }\n const left =\n samples[segmentIndex]!;\n const right =\n samples[\n segmentIndex + 1\n ]!;\n const duration =\n right\n .timeSecondsFromCaptureReference -\n left\n .timeSecondsFromCaptureReference;\n const phase =\n duration === 0\n ? 0\n : (\n timeSeconds -\n left\n .timeSecondsFromCaptureReference\n ) /\n duration;\n const a =\n left\n .angularDisplacementRad[\n axis\n ];\n const b =\n right\n .angularDisplacementRad[\n axis\n ];\n return (\n a +\n (b - a) * phase\n );\n}\n\nfunction interpolateAxis(\n disturbance: DisturbanceIndex,\n timeSeconds: number,\n axis:\n StabilizationRotationAxis\n): number {\n return interpolateDisturbanceSegment(\n disturbance,\n locateDisturbanceSegment(\n disturbance,\n timeSeconds\n ),\n timeSeconds,\n axis\n );\n}\n\nfunction axisValue(\n state:\n StabilizationAngularStateRad,\n axis:\n StabilizationRotationAxis\n): number {\n return state[axis];\n}\n\nfunction setAxisValue(\n state:\n StabilizationAngularStateRad,\n axis:\n StabilizationRotationAxis,\n value: number\n): void {\n state[axis] = value;\n}\n\nfunction clampSymmetric(\n value: number,\n limit: number\n): number {\n return Math.max(\n -limit,\n Math.min(limit, value)\n );\n}\n\ntype AxisResponseIndex = ReadonlyMap<\n StabilizationRotationAxis,\n StabilizationSystemProfile[\"axisResponses\"][number]\n>;\n\n/** Built once per calculation. Later entries win, as with a per-evaluation Map. */\nfunction indexAxisResponses(\n profile:\n StabilizationSystemProfile\n): AxisResponseIndex {\n return new Map(\n profile.axisResponses.map(\n (response) => [\n response.axis,\n response\n ] as const\n )\n );\n}\n\nfunction evaluateAtTime(\n disturbance: DisturbanceIndex,\n profile:\n StabilizationSystemProfile,\n responses: AxisResponseIndex,\n timeSeconds: number\n): StabilizedRotationSample {\n // One segment lookup serves all three axes at the same time.\n const segment =\n locateDisturbanceSegment(\n disturbance,\n timeSeconds\n );\n const current:\n StabilizationAngularStateRad = {\n pitch:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"pitch\"\n ),\n yaw:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"yaw\"\n ),\n roll:\n interpolateDisturbanceSegment(\n disturbance,\n segment,\n timeSeconds,\n \"roll\"\n )\n };\n const correction:\n StabilizationAngularStateRad = {\n pitch: 0,\n yaw: 0,\n roll: 0\n };\n const residual:\n StabilizationAngularStateRad = {\n ...current\n };\n\n const axes =\n [\"pitch\", \"yaw\", \"roll\"] as const;\n const resolvedAxes =\n axes.map((axis) => {\n const response =\n responses.get(axis);\n const bypassed =\n profile.panningPolicy.kind ===\n \"declared-axis-bypass\" &&\n profile.panningPolicy.axis ===\n axis;\n\n if (\n profile.architecture ===\n \"off\" ||\n response === undefined ||\n bypassed\n ) {\n return {\n axis,\n disturbanceAngleRad:\n axisValue(\n current,\n axis\n ),\n delayedMeasuredAngleRad:\n 0,\n requestedCorrectionAngleRad:\n 0,\n appliedCorrectionAngleRad:\n 0,\n residualAngleRad:\n axisValue(\n current,\n axis\n ),\n correctionGain:\n response?.correctionGain\n .value ?? 0,\n latencySeconds:\n response?.latencySeconds\n .value ?? 0,\n maximumCorrectionAngleRad:\n response\n ?.maximumCorrectionAngleRad\n .value ?? 0,\n bypassedForDeclaredPan:\n bypassed,\n correctionLimitReached:\n false\n };\n }\n\n const delayedTime =\n timeSeconds -\n response\n .latencySeconds.value;\n const delayedMeasured =\n delayedTime < 0\n ? 0\n : interpolateAxis(\n disturbance,\n delayedTime,\n axis\n );\n const requested =\n delayedMeasured *\n response\n .correctionGain.value;\n const applied =\n clampSymmetric(\n requested,\n response\n .maximumCorrectionAngleRad\n .value\n );\n const residualAngle =\n axisValue(\n current,\n axis\n ) -\n applied;\n\n setAxisValue(\n correction,\n axis,\n applied\n );\n setAxisValue(\n residual,\n axis,\n residualAngle\n );\n\n return {\n axis,\n disturbanceAngleRad:\n axisValue(\n current,\n axis\n ),\n delayedMeasuredAngleRad:\n delayedMeasured,\n requestedCorrectionAngleRad:\n requested,\n appliedCorrectionAngleRad:\n applied,\n residualAngleRad:\n residualAngle,\n correctionGain:\n response\n .correctionGain.value,\n latencySeconds:\n response\n .latencySeconds.value,\n maximumCorrectionAngleRad:\n response\n .maximumCorrectionAngleRad\n .value,\n bypassedForDeclaredPan:\n false,\n correctionLimitReached:\n applied !== requested\n };\n });\n\n return {\n timeSecondsFromCaptureReference:\n timeSeconds,\n disturbanceAngularDisplacementRad:\n current,\n appliedCorrectionAngularDisplacementRad:\n correction,\n residualAngularDisplacementRad:\n residual,\n axes:\n resolvedAxes\n };\n}\n\n/**\n * Runs the declared generic per-axis controller against an explicit angular disturbance trajectory.\n * Returns the residual motion, with diagnostics for latency and travel limits.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param input - CalculateStabilizedRotationTrajectoryInput. See that type for coordinates, units and profile binding.\n * @returns CalculationResult<StabilizedRotationTrajectory>. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function calculateStabilizedRotationTrajectory(\n input:\n CalculateStabilizedRotationTrajectoryInput\n): CalculationResult<StabilizedRotationTrajectory> {\n requireInputKeys(input, \"calculateStabilizedRotationTrajectory\", [\"disturbance\", \"profile\", \"captureKind\"]);\n const disturbance =\n parseStabilizationDisturbanceTrajectory(\n input.disturbance\n );\n const profile =\n parseStabilizationSystemProfile(\n input.profile\n );\n\n if (\n input.captureKind !==\n profile.captureKind\n ) {\n throw new InvalidScientificInputError(\n \"captureKind must exactly match the stabilization profile captureKind.\"\n );\n }\n\n const disturbanceIndex =\n indexDisturbance(disturbance);\n const responses =\n indexAxisResponses(profile);\n const samples =\n disturbance.samples.map(\n (sample) =>\n evaluateAtTime(\n disturbanceIndex,\n profile,\n responses,\n sample\n .timeSecondsFromCaptureReference\n )\n );\n\n return approximationResult(\n {\n profileId:\n profile.profileId,\n profileVersion:\n profile.profileVersion,\n trajectoryId:\n disturbance.trajectoryId,\n architecture:\n profile.architecture,\n captureKind:\n input.captureKind,\n timeReference:\n \"first-opening-boundary-phase\",\n samples,\n correctionModel:\n \"delayed-linear-image-equivalent-angular-response\",\n supportStateConsumed:\n false,\n translationCorrectionModeled:\n false,\n digitalStabilizationApplied:\n false,\n digitalStabilizationOwnedBy:\n \"downstream-geometric-correction-composition\",\n coordinatedCorrectionDoubleCounted:\n false,\n zeroDisturbanceCanCreateMotion:\n false\n },\n \"generic-time-domain-physical-stabilization\",\n \"1.0.0\",\n [\n \"The stabilization response is a generic synthetic image-equivalent rotational correction, not a manufacturer-specific IBIS/OIS calibration.\",\n \"Correction uses explicit per-axis gain, latency and symmetric angular correction limits.\",\n \"A coordinated profile allocates one total correction between body and lens for descriptive ownership only; the total correction is applied once.\",\n \"Support state is not an input and never silently toggles stabilization.\",\n \"Declared panning bypass suppresses correction only on the explicitly selected axis; pan intent is never inferred.\",\n \"Camera translation/parallax correction is not modeled because translational image motion depends on scene depth.\",\n \"Digital stabilization is a separate downstream geometric/crop/resampling domain.\",\n \"CIPA-style stop ratings are not used as a dynamic response function.\",\n \"The legacy stabilizationStopsEquivalent approximation remains unchanged.\"\n ]\n );\n}\n\ntype ExposureWindowSample =\n ResolvedCaptureModeTiming[\"exposureWindows\"][\"samples\"][number];\ntype ExposureWindowIndex = ReadonlyMap<\n unknown,\n ReadonlyMap<unknown, readonly ExposureWindowSample[]>\n>;\n\n/**\n * Groups the committed exposure-window samples by native point, once per calculation, and keeps their\n * order. Map keys compare with SameValueZero, so lookups are filtered again with the original `===`\n * test: NaN never matches, and +0 matches -0.\n */\nfunction indexExposureWindows(\n timing:\n ResolvedCaptureModeTiming\n): ExposureWindowIndex {\n requireInputObject(timing, \"timing\");\n requireInputObject(timing.exposureWindows, \"timing.exposureWindows\");\n if (!Array.isArray(timing.exposureWindows.samples)) throw new InvalidConfigurationError(\"timing.exposureWindows.samples must be an array.\");\n timing.exposureWindows.samples.forEach((sample, index) => {\n requireInputObject(sample, \"timing.exposureWindows.samples[\" + index + \"]\");\n requireInputObject(sample.pointNative, \"timing.exposureWindows.samples[\" + index + \"].pointNative\");\n });\n const byX =\n new Map<\n unknown,\n Map<unknown, ExposureWindowSample[]>\n >();\n for (const sample of timing.exposureWindows.samples) {\n let byY =\n byX.get(sample.pointNative.x);\n if (byY === undefined) {\n byY = new Map();\n byX.set(\n sample.pointNative.x,\n byY\n );\n }\n const bucket =\n byY.get(sample.pointNative.y);\n if (bucket === undefined) {\n byY.set(\n sample.pointNative.y,\n [sample]\n );\n } else {\n bucket.push(sample);\n }\n }\n return byX;\n}\n\nfunction localExposureForPoint(\n windows: ExposureWindowIndex,\n point:\n RasterPoint\n): {\n start: number;\n end: number;\n duration: number;\n} {\n const matches =\n (\n windows\n .get(point.x)\n ?.get(point.y) ?? []\n ).filter(\n (sample) =>\n sample.pointNative.x ===\n point.x &&\n sample.pointNative.y ===\n point.y\n );\n if (matches.length !== 1) {\n throw new InvalidScientificInputError(\n \"Each stabilization sample point must match exactly one committed exposure-window sample point.\"\n );\n }\n const match =\n matches[0]!;\n return {\n start:\n match\n .startOffsetSecondsFromOpeningReference,\n end:\n match\n .endOffsetSecondsFromOpeningReference,\n duration:\n match\n .localExposureDurationSeconds\n };\n}\n\n/**\n * Feeds the residual stabilized rotation into the existing local-exposure temporal mapping. Shutter\n * timing is not changed, and no blur radius is invented.\n *\n * The generic stabilizer takes a declared angular disturbance (camera shake) and applies a per-axis\n * response, latency, travel limits and a panning policy. The leftover (residual) motion feeds the\n * existing temporal mapping. No commercial IBIS (in-body) or OIS (optical) calibration is supplied,\n * no arbitrary \"stops\" rating is used, and body/lens coordination is never inferred.\n * @param input - CalculateStabilizedCaptureTemporalSamplesInput. See that type for coordinates, units and profile binding.\n * @returns CalculationResult<StabilizedCaptureTemporalSamples>. The result states its shape and scientific status; a successful call does not imply calibration.\n *\n * @see docs/API_REFERENCE.md for the root export and exact type graph.\n */\nexport function calculateStabilizedCaptureTemporalSamples(\n input:\n CalculateStabilizedCaptureTemporalSamplesInput\n): CalculationResult<StabilizedCaptureTemporalSamples> {\n requireInputKeys(input, \"calculateStabilizedCaptureTemporalSamples\", [\"disturbance\", \"profile\", \"captureKind\", \"timing\", \"samplePointsNative\", \"temporalSampleCount\"]);\n requireInputObject(input.timing, \"timing\");\n const disturbance =\n parseStabilizationDisturbanceTrajectory(\n input.disturbance\n );\n const profile =\n parseStabilizationSystemProfile(\n input.profile\n );\n if (\n input.captureKind !==\n profile.captureKind\n ) {\n throw new InvalidScientificInputError(\n \"captureKind must exactly match the stabilization profile captureKind.\"\n );\n }\n requirePositiveInteger(\n \"temporalSampleCount\",\n input.temporalSampleCount\n );\n if (\n !Array.isArray(\n input.samplePointsNative\n ) ||\n input.samplePointsNative.length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"samplePointsNative must be a non-empty array.\"\n );\n }\n input.samplePointsNative.forEach((point, index) => requireInputObject(point, \"samplePointsNative[\" + index + \"]\"));\n\n const totalNodeCount =\n input.temporalSampleCount *\n input.samplePointsNative.length;\n if (\n !Number.isSafeInteger(\n totalNodeCount\n )\n ) {\n throw new InvalidScientificInputError(\n \"temporalSampleCount × samplePointsNative.length must remain a safe integer.\"\n );\n }\n\n const disturbanceIndex =\n indexDisturbance(disturbance);\n const responses =\n indexAxisResponses(profile);\n let exposureWindowIndex:\n ExposureWindowIndex | undefined;\n const points =\n input.samplePointsNative.map(\n (point) => {\n exposureWindowIndex ??=\n indexExposureWindows(\n input.timing\n );\n const exposure =\n localExposureForPoint(\n exposureWindowIndex,\n point\n );\n const normalizedTimeWeight =\n 1 /\n input.temporalSampleCount;\n const timeMeasureSeconds =\n exposure.duration /\n input.temporalSampleCount;\n\n const nodes =\n Array.from(\n {\n length:\n input.temporalSampleCount\n },\n (\n _,\n temporalSampleIndex\n ) => {\n const localExposurePhase =\n (\n temporalSampleIndex +\n 0.5\n ) /\n input.temporalSampleCount;\n const captureTime =\n exposure.start +\n localExposurePhase *\n exposure.duration;\n return {\n temporalSampleIndex,\n localExposurePhase,\n captureTimeSecondsFromReference:\n captureTime,\n normalizedTimeWeight,\n timeMeasureSeconds,\n stabilization:\n evaluateAtTime(\n disturbanceIndex,\n profile,\n responses,\n captureTime\n )\n };\n }\n );\n\n return {\n destinationPointNative: {\n ...point\n },\n localExposureWindow: {\n startSecondsFromCaptureReference:\n exposure.start,\n endSecondsFromCaptureReference:\n exposure.end,\n durationSeconds:\n exposure.duration\n },\n nodes\n };\n }\n );\n\n return approximationResult(\n {\n profileId:\n profile.profileId,\n trajectoryId:\n disturbance.trajectoryId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n captureKind:\n input.captureKind,\n architecture:\n profile.architecture,\n timeReference:\n \"first-opening-boundary-phase\",\n quadratureScheme:\n \"uniform-midpoint\",\n temporalSampleCount:\n input.temporalSampleCount,\n points,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n supportStateConsumed:\n false,\n translationCorrectionModeled:\n false,\n digitalStabilizationApplied:\n false\n },\n \"capture-local-stabilization-temporal-sampling\",\n \"1.0.0\",\n [\n \"Stabilization is evaluated at deterministic midpoint nodes inside each authoritative local exposure window of the exposure-window model.\",\n \"Sensor data-readout timing is not substituted for exposure timing.\",\n \"The result is rotational disturbance/correction/residual state only; it does not itself calculate image-plane mapping, radiance, blur, PSF or output pixels.\",\n \"Translation/parallax, subject motion, shutter shock, support vibration sources and digital stabilization remain separate domains.\"\n ]\n );\n}\n"]}
@@ -28,10 +28,14 @@ one-call capture, see the [Quick Start](QUICK_START.md). For every export, see t
28
28
  | Blur of an out-of-focus subject | [`calculateDefocusCircle`](api/optics-depth-of-field.md#calculatedefocuscircle) | Geometric blur-circle diameter at the sensor. |
29
29
  | Check a defocus blur before rendering it | [`calculateDefocusDiscKernelRadius`](api/optics-defocus-disc-kernel.md#calculatedefocusdisckernelradius) | Whether `lens.defocus` renders the disc or refuses it (kernel radius at most `DEFOCUS_DISC_KERNEL_MAXIMUM_RADIUS_SITES`, 64 sites), and by how much it is over. |
30
30
  | A generic catalogue lens and its character | [`resolveGenericLens`](api/equipment-generic-lens-catalogue.md#resolvegenericlens) | 30 Photivra primes ("PV 50 1.2 Pro", "PV 50 1.8"), every value a labelled approximation; `simulateCapture` renders one with `lens.catalogue` ([catalogue](https://github.com/Photivra/photivra/blob/main/docs/LENS_CATALOGUE.md)). |
31
+ | Render a lens by its physical focal length and f-number | [`IDEAL_LENS_LIMITS`](api/equipment-ideal-lens.md#ideal_lens_limits) | `simulateCapture` / the display view with `lens.ideal: { focalLengthMm }` and `lens.fNumber`: an ideal thin lens on any sensor, f/0.5–f/128, 1–4000 mm; no crop-factor scaling. |
31
32
  | Field (angle) of view | [`calculateFieldOfView`](api/camera-field-of-view.md#calculatefieldofview) | Pass the sensor width, height or diagonal for that angle. |
32
33
  | Crop factor and 35 mm-equivalent focal length | [`calculateEquivalentFocalLength35Mm`](api/camera-equivalent-focal-length.md#calculateequivalentfocallength35mm) | Diagonal-based, against a 36 × 24 mm frame. |
34
+ | Equivalent f-number, sensor area ratio and angles of view of a lens on a sensor | [`calculateSensorEquivalence`](api/camera-sensor-equivalence.md#calculatesensorequivalence) | Call once per sensor. `equivalentFNumber` is for depth of field, blur and total light (an approximation); `exposureFNumber` is the f-number on the lens. `basis` says exact or approximated for every value. |
35
+ | Blur circle as a share of the frame or on a print | [`calculateBlurShareOfFrame`](api/camera-sensor-equivalence.md#calculateblurshareofframe) | Equal shares of the diagonal look the same at the same output size. |
33
36
  | Pixels left after a centred crop | [`calculateCenteredCrop`](api/output-crop.md#calculatecenteredcrop) | Keeps the aspect ratio to whole pixels. |
34
37
  | Motion blur for a shutter speed | [`calculateProjectedMotionBlur`](api/motion-projected-motion.md#calculateprojectedmotionblur) | Subject position and velocity in metres; blur in mm, and in pixels if you give a pixel pitch. |
38
+ | Shutter time with an ND filter | [`calculateFilteredExposureTime`](api/exposure-filtered-exposure-time.md#calculatefilteredexposuretime) | Pass `GENERIC_ND_FILTER_PROFILES[3 | 6 | 10]` (idealized, exactly 2^-N) or your own front-of-lens filter profile(s), and optionally a shutter dial (for example `GENERIC_THIRD_STOP_SHUTTER_SECONDS`) for the nearest dial value. 1/125 s with a 10-stop filter → ≈ 8.19 s (8 s on the dial). |
35
39
  | Video shutter angle to exposure time | [`calculateShutterAngleExposureSeconds`](api/motion-video-sequence.md#calculateshutterangleexposureseconds) | Positional arguments: frame rate (Hz), angle (degrees). |
36
40
  | Diffraction spot size | [`calculateAiryDisk`](api/optics-diffraction.md#calculateairydisk) | Ideal circular aperture; you choose the wavelength. |
37
41
  | Photons to electrons | [`calculatePhotoelectrons`](api/sensor-signal-noise.md#calculatephotoelectrons) | Mean value; you supply the quantum efficiency. |
@@ -1,6 +1,6 @@
1
1
  # Public API reference
2
2
 
3
- Generated from the exact root exports for **@photivra/engine 2.17.0 / root contract 2.17.0** by `node scripts/generate-api-reference.mjs`. No module deep import is supported.
3
+ Generated from the exact root exports for **@photivra/engine 2.19.0 / root contract 2.19.0** by `node scripts/generate-api-reference.mjs`. No module deep import is supported.
4
4
 
5
5
  Use [the developer guide](https://github.com/Photivra/photivra/blob/main/docs/DEVELOPERS.md) for executable paths and scientific boundaries. Types are contracts, not runtime validation: parse untrusted data, preserve units/reference frames, read assessment blockers, and retain evidence/limitations. Optional properties do not imply a universal default. Model/schema IDs remain independent of the distribution.
6
6
 
@@ -16,7 +16,9 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
16
16
  | Depth of field, hyperfocal distance and defocus blur | [`calculateDepthOfField`](api/optics-depth-of-field.md#calculatedepthoffield), [`calculateDefocusCircle`](api/optics-depth-of-field.md#calculatedefocuscircle) |
17
17
  | Field of view | [`calculateFieldOfView`](api/camera-field-of-view.md#calculatefieldofview) |
18
18
  | Crop factor, 35 mm-equivalent focal length and crops | [`calculateEquivalentFocalLength35Mm`](api/camera-equivalent-focal-length.md#calculateequivalentfocallength35mm), [`calculateCenteredCrop`](api/output-crop.md#calculatecenteredcrop) |
19
+ | Equivalent f-number, sensor area and blur as a share of the frame | [`calculateSensorEquivalence`](api/camera-sensor-equivalence.md#calculatesensorequivalence), [`calculateBlurShareOfFrame`](api/camera-sensor-equivalence.md#calculateblurshareofframe) |
19
20
  | Motion blur and shutter speed | [`calculateProjectedMotionBlur`](api/motion-projected-motion.md#calculateprojectedmotionblur), [`calculateShutterAngleExposureSeconds`](api/motion-video-sequence.md#calculateshutterangleexposureseconds) |
21
+ | Shutter time with an ND filter | [`calculateFilteredExposureTime`](api/exposure-filtered-exposure-time.md#calculatefilteredexposuretime) |
20
22
  | Diffraction | [`calculateAiryDisk`](api/optics-diffraction.md#calculateairydisk) |
21
23
  | Sensor signal, noise and SNR | [`calculatePhotoelectrons`](api/sensor-signal-noise.md#calculatephotoelectrons), [`calculateSignalToNoise`](api/sensor-signal-noise.md#calculatesignaltonoise) |
22
24
  | Colour temperature | [`calculateChromaticityFromCorrelatedColorTemperature`](api/color-illuminants.md#calculatechromaticityfromcorrelatedcolortemperature), [`calculateCorrelatedColorTemperature`](api/color-illuminants.md#calculatecorrelatedcolortemperature) |
@@ -79,6 +81,24 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
79
81
  | [`CalculateProjectedObjectSizeInput`](api/camera-projected-object-size.md#calculateprojectedobjectsizeinput) | Type |
80
82
  | [`ProjectedObjectSize`](api/camera-projected-object-size.md#projectedobjectsize) | Type |
81
83
 
84
+ ## camera/sensor-equivalence.ts
85
+
86
+ [Detailed contracts](api/camera-sensor-equivalence.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/camera/sensor-equivalence.ts)
87
+
88
+ | Export | Kind |
89
+ | --- | --- |
90
+ | [`BlurShareOfFrame`](api/camera-sensor-equivalence.md#blurshareofframe) | Type |
91
+ | [`BlurShareOfPrint`](api/camera-sensor-equivalence.md#blurshareofprint) | Type |
92
+ | [`calculateBlurShareOfFrame`](api/camera-sensor-equivalence.md#calculateblurshareofframe) | Runtime |
93
+ | [`CalculateBlurShareOfFrameInput`](api/camera-sensor-equivalence.md#calculateblurshareofframeinput) | Type |
94
+ | [`calculateSensorEquivalence`](api/camera-sensor-equivalence.md#calculatesensorequivalence) | Runtime |
95
+ | [`CalculateSensorEquivalenceInput`](api/camera-sensor-equivalence.md#calculatesensorequivalenceinput) | Type |
96
+ | [`EquivalenceExactness`](api/camera-sensor-equivalence.md#equivalenceexactness) | Type |
97
+ | [`EquivalenceValueBasis`](api/camera-sensor-equivalence.md#equivalencevaluebasis) | Type |
98
+ | [`SensorEquivalence`](api/camera-sensor-equivalence.md#sensorequivalence) | Type |
99
+ | [`SensorEquivalenceFieldOfView`](api/camera-sensor-equivalence.md#sensorequivalencefieldofview) | Type |
100
+ | [`SensorEquivalenceQuantity`](api/camera-sensor-equivalence.md#sensorequivalencequantity) | Type |
101
+
82
102
  ## capture/capture-export-metadata.ts
83
103
 
84
104
  [Detailed contracts](api/capture-capture-export-metadata.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/capture/capture-export-metadata.ts)
@@ -896,6 +916,14 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
896
916
  | [`resolveGenericEquipmentTierCatalog`](api/equipment-generic-tier-presets.md#resolvegenericequipmenttiercatalog) | Runtime |
897
917
  | [`resolveGenericEquipmentTierLensProfiles`](api/equipment-generic-tier-presets.md#resolvegenericequipmenttierlensprofiles) | Runtime |
898
918
 
919
+ ## equipment/ideal-lens.ts
920
+
921
+ [Detailed contracts](api/equipment-ideal-lens.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/equipment/ideal-lens.ts)
922
+
923
+ | Export | Kind |
924
+ | --- | --- |
925
+ | [`IDEAL_LENS_LIMITS`](api/equipment-ideal-lens.md#ideal_lens_limits) | Runtime |
926
+
899
927
  ## equipment/iso-capabilities.ts
900
928
 
901
929
  [Detailed contracts](api/equipment-iso-capabilities.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/equipment/iso-capabilities.ts)
@@ -1029,6 +1057,18 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
1029
1057
  | [`RelativeOpticalExposure`](api/exposure-exposure.md#relativeopticalexposure) | Type |
1030
1058
  | [`RelativeRenderedExposure`](api/exposure-exposure.md#relativerenderedexposure) | Type |
1031
1059
 
1060
+ ## exposure/filtered-exposure-time.ts
1061
+
1062
+ [Detailed contracts](api/exposure-filtered-exposure-time.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/exposure/filtered-exposure-time.ts)
1063
+
1064
+ | Export | Kind |
1065
+ | --- | --- |
1066
+ | [`calculateFilteredExposureTime`](api/exposure-filtered-exposure-time.md#calculatefilteredexposuretime) | Runtime |
1067
+ | [`CalculateFilteredExposureTimeInput`](api/exposure-filtered-exposure-time.md#calculatefilteredexposuretimeinput) | Type |
1068
+ | [`FILTERED_EXPOSURE_DEFAULT_WAVELENGTH_NANOMETERS`](api/exposure-filtered-exposure-time.md#filtered_exposure_default_wavelength_nanometers) | Runtime |
1069
+ | [`FilteredExposureDialSetting`](api/exposure-filtered-exposure-time.md#filteredexposuredialsetting) | Type |
1070
+ | [`FilteredExposureTime`](api/exposure-filtered-exposure-time.md#filteredexposuretime) | Type |
1071
+
1032
1072
  ## exposure/flash-ttl.ts
1033
1073
 
1034
1074
  [Detailed contracts](api/exposure-flash-ttl.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/exposure/flash-ttl.ts)
@@ -1240,6 +1280,14 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
1240
1280
  | [`EvaluateColorPatchReflectanceInput`](api/facade-color-patches.md#evaluatecolorpatchreflectanceinput) | Type |
1241
1281
  | [`getColorPatchSet`](api/facade-color-patches.md#getcolorpatchset) | Runtime |
1242
1282
 
1283
+ ## facade/develop-joined-parts.ts
1284
+
1285
+ [Detailed contracts](api/facade-develop-joined-parts.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/develop-joined-parts.ts)
1286
+
1287
+ | Export | Kind |
1288
+ | --- | --- |
1289
+ | [`simulateCaptureFromParts`](api/facade-develop-joined-parts.md#simulatecapturefromparts) | Runtime |
1290
+
1243
1291
  ## facade/display-view-gpu.ts
1244
1292
 
1245
1293
  [Detailed contracts](api/facade-display-view-gpu.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/facade/display-view-gpu.ts)
@@ -1319,6 +1367,8 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
1319
1367
  | [`SimulateCaptureExposureMode`](api/facade-simulate-capture.md#simulatecaptureexposuremode) | Type |
1320
1368
  | [`SimulateCaptureFastOption`](api/facade-simulate-capture.md#simulatecapturefastoption) | Type |
1321
1369
  | [`SimulateCaptureFastReport`](api/facade-simulate-capture.md#simulatecapturefastreport) | Type |
1370
+ | [`SimulateCaptureLensCatalogueRecord`](api/facade-simulate-capture.md#simulatecapturelenscataloguerecord) | Type |
1371
+ | [`SimulateCaptureLensCorrections`](api/facade-simulate-capture.md#simulatecapturelenscorrections) | Type |
1322
1372
  | [`SimulateCaptureLensDistortion`](api/facade-simulate-capture.md#simulatecapturelensdistortion) | Type |
1323
1373
  | [`SimulateCaptureMetering`](api/facade-simulate-capture.md#simulatecapturemetering) | Type |
1324
1374
  | [`SimulateCaptureMotion`](api/facade-simulate-capture.md#simulatecapturemotion) | Type |
@@ -1711,6 +1761,16 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
1711
1761
  | [`resolveFrontOfLensFilterTransmission`](api/optics-front-of-lens-filter.md#resolvefrontoflensfiltertransmission) | Runtime |
1712
1762
  | [`ResolveFrontOfLensFilterTransmissionInput`](api/optics-front-of-lens-filter.md#resolvefrontoflensfiltertransmissioninput) | Type |
1713
1763
 
1764
+ ## optics/generic-nd-filter-presets.ts
1765
+
1766
+ [Detailed contracts](api/optics-generic-nd-filter-presets.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/optics/generic-nd-filter-presets.ts)
1767
+
1768
+ | Export | Kind |
1769
+ | --- | --- |
1770
+ | [`GENERIC_ND_FILTER_PROFILES`](api/optics-generic-nd-filter-presets.md#generic_nd_filter_profiles) | Runtime |
1771
+ | [`GENERIC_ND_FILTER_STOPS`](api/optics-generic-nd-filter-presets.md#generic_nd_filter_stops) | Runtime |
1772
+ | [`GenericNdFilterStops`](api/optics-generic-nd-filter-presets.md#genericndfilterstops) | Type |
1773
+
1714
1774
  ## optics/illumination-vignetting.ts
1715
1775
 
1716
1776
  [Detailed contracts](api/optics-illumination-vignetting.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/optics/illumination-vignetting.ts)
@@ -2067,6 +2127,14 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
2067
2127
  | [`CalculateCenteredCropInput`](api/output-crop.md#calculatecenteredcropinput) | Type |
2068
2128
  | [`CenteredCrop`](api/output-crop.md#centeredcrop) | Type |
2069
2129
 
2130
+ ## output/developed-lens-corrections.ts
2131
+
2132
+ [Detailed contracts](api/output-developed-lens-corrections.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/output/developed-lens-corrections.ts)
2133
+
2134
+ | Export | Kind |
2135
+ | --- | --- |
2136
+ | [`GENERIC_LENS_CORRECTION_CHANNEL_WAVELENGTHS_NM`](api/output-developed-lens-corrections.md#generic_lens_correction_channel_wavelengths_nm) | Runtime |
2137
+
2070
2138
  ## output/generic-lens-corrections.ts
2071
2139
 
2072
2140
  [Detailed contracts](api/output-generic-lens-corrections.md) · [Source](https://github.com/Photivra/photivra/blob/main/src/output/generic-lens-corrections.ts)
@@ -2075,7 +2143,6 @@ Start here to find a function by task. [Using Photivra from an agent](AGENT_GUID
2075
2143
  | --- | --- |
2076
2144
  | [`createGenericLensCorrectionProfile`](api/output-generic-lens-corrections.md#creategenericlenscorrectionprofile) | Runtime |
2077
2145
  | [`CreateGenericLensCorrectionProfileInput`](api/output-generic-lens-corrections.md#creategenericlenscorrectionprofileinput) | Type |
2078
- | [`GENERIC_LENS_CORRECTION_CHANNEL_WAVELENGTHS_NM`](api/output-generic-lens-corrections.md#generic_lens_correction_channel_wavelengths_nm) | Runtime |
2079
2146
 
2080
2147
  ## output/geometric-transforms.ts
2081
2148