@photivra/engine 2.18.0 → 2.20.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 (335) hide show
  1. package/CHANGELOG.md +179 -1
  2. package/CITATION.cff +1 -1
  3. package/NODE_SUPPORT.md +7 -5
  4. package/README.md +6 -6
  5. package/SECURITY.md +1 -1
  6. package/THIRD_PARTY.md +14 -10
  7. package/dist/capture/dng-lens-correction-opcodes.d.ts +32 -0
  8. package/dist/capture/dng-lens-correction-opcodes.js +119 -0
  9. package/dist/capture/dng-lens-correction-opcodes.js.map +1 -0
  10. package/dist/capture/focus-control.js +2 -75
  11. package/dist/capture/focus-control.js.map +1 -1
  12. package/dist/capture/native-environment-lean.d.ts +1 -0
  13. package/dist/capture/native-environment-lean.js +2 -6
  14. package/dist/capture/native-environment-lean.js.map +1 -1
  15. package/dist/capture/native-environment-optical-stage.d.ts +1 -0
  16. package/dist/capture/native-environment-optical-stage.js +2 -5
  17. package/dist/capture/native-environment-optical-stage.js.map +1 -1
  18. package/dist/capture/native-environment-raw.js +1 -5
  19. package/dist/capture/native-environment-raw.js.map +1 -1
  20. package/dist/capture/native-raw-dng.d.ts +6 -0
  21. package/dist/capture/native-raw-dng.js +16 -2
  22. package/dist/capture/native-raw-dng.js.map +1 -1
  23. package/dist/capture/release-sequence.js +2 -47
  24. package/dist/capture/release-sequence.js.map +1 -1
  25. package/dist/capture/sensor-raw-producer.js +3 -5
  26. package/dist/capture/sensor-raw-producer.js.map +1 -1
  27. package/dist/color/white-balance.d.ts +2 -0
  28. package/dist/color/white-balance.js +3 -56
  29. package/dist/color/white-balance.js.map +1 -1
  30. package/dist/composition/image-formation-plan.d.ts +1 -0
  31. package/dist/composition/image-formation-plan.js +3 -49
  32. package/dist/composition/image-formation-plan.js.map +1 -1
  33. package/dist/core/evidence-provenance.js +1 -16
  34. package/dist/core/evidence-provenance.js.map +1 -1
  35. package/dist/core/record-validation.d.ts +54 -0
  36. package/dist/core/record-validation.js +176 -0
  37. package/dist/core/record-validation.js.map +1 -1
  38. package/dist/core/scientific-assurance.js +1 -18
  39. package/dist/core/scientific-assurance.js.map +1 -1
  40. package/dist/core/shared-helpers.d.ts +35 -0
  41. package/dist/core/shared-helpers.js +38 -0
  42. package/dist/core/shared-helpers.js.map +1 -0
  43. package/dist/core/spectral-composition.js +1 -36
  44. package/dist/core/spectral-composition.js.map +1 -1
  45. package/dist/core/spectral.js +1 -19
  46. package/dist/core/spectral.js.map +1 -1
  47. package/dist/core/version.d.ts +1 -1
  48. package/dist/core/version.js +1 -1
  49. package/dist/core/version.js.map +1 -1
  50. package/dist/equipment/exposure-capabilities.d.ts +1 -0
  51. package/dist/equipment/exposure-capabilities.js +2 -36
  52. package/dist/equipment/exposure-capabilities.js.map +1 -1
  53. package/dist/equipment/generic-lens-catalogue.d.ts +8 -2
  54. package/dist/equipment/generic-lens-catalogue.js +31 -2
  55. package/dist/equipment/generic-lens-catalogue.js.map +1 -1
  56. package/dist/equipment/generic-tier-assets.js +2 -3
  57. package/dist/equipment/generic-tier-assets.js.map +1 -1
  58. package/dist/equipment/generic-tier-presets.js +2 -3
  59. package/dist/equipment/generic-tier-presets.js.map +1 -1
  60. package/dist/equipment/iso-capabilities.js +2 -49
  61. package/dist/equipment/iso-capabilities.js.map +1 -1
  62. package/dist/equipment/metering-capabilities.js +1 -26
  63. package/dist/equipment/metering-capabilities.js.map +1 -1
  64. package/dist/equipment/release-capabilities.js +1 -53
  65. package/dist/equipment/release-capabilities.js.map +1 -1
  66. package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
  67. package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
  68. package/dist/exposure/exposure-duration-control.js +1 -16
  69. package/dist/exposure/exposure-duration-control.js.map +1 -1
  70. package/dist/exposure/exposure-mode-resolver.js +1 -17
  71. package/dist/exposure/exposure-mode-resolver.js.map +1 -1
  72. package/dist/exposure/filtered-exposure-time.d.ts +93 -0
  73. package/dist/exposure/filtered-exposure-time.js +129 -0
  74. package/dist/exposure/filtered-exposure-time.js.map +1 -0
  75. package/dist/exposure/flash-ttl.d.ts +1 -0
  76. package/dist/exposure/flash-ttl.js +1 -1
  77. package/dist/exposure/flash-ttl.js.map +1 -1
  78. package/dist/exposure/flash.js +1 -49
  79. package/dist/exposure/flash.js.map +1 -1
  80. package/dist/exposure/metering-scene-radiance.js +1 -25
  81. package/dist/exposure/metering-scene-radiance.js.map +1 -1
  82. package/dist/exposure/metering-target.js +1 -30
  83. package/dist/exposure/metering-target.js.map +1 -1
  84. package/dist/exposure/metering-temporal.js +1 -8
  85. package/dist/exposure/metering-temporal.js.map +1 -1
  86. package/dist/exposure/metering.js +1 -72
  87. package/dist/exposure/metering.js.map +1 -1
  88. package/dist/exposure/program-line.js +1 -45
  89. package/dist/exposure/program-line.js.map +1 -1
  90. package/dist/facade/develop-joined-parts.d.ts +29 -0
  91. package/dist/facade/develop-joined-parts.js +33 -0
  92. package/dist/facade/develop-joined-parts.js.map +1 -0
  93. package/dist/facade/display-view-gpu.d.ts +7 -4
  94. package/dist/facade/display-view-gpu.js +4 -4
  95. package/dist/facade/display-view-gpu.js.map +1 -1
  96. package/dist/facade/display-view-lens-signal.d.ts +1 -1
  97. package/dist/facade/display-view-lens-signal.js +5 -3
  98. package/dist/facade/display-view-lens-signal.js.map +1 -1
  99. package/dist/facade/display-view.d.ts +3 -1
  100. package/dist/facade/display-view.js +1 -1
  101. package/dist/facade/display-view.js.map +1 -1
  102. package/dist/facade/fast-methods.d.ts +50 -0
  103. package/dist/facade/fast-methods.js +50 -0
  104. package/dist/facade/fast-methods.js.map +1 -0
  105. package/dist/facade/fast-resolution.d.ts +12 -0
  106. package/dist/facade/fast-resolution.js +18 -0
  107. package/dist/facade/fast-resolution.js.map +1 -0
  108. package/dist/facade/generic-lens-capture.d.ts +6 -3
  109. package/dist/facade/generic-lens-capture.js +6 -3
  110. package/dist/facade/generic-lens-capture.js.map +1 -1
  111. package/dist/facade/simulate-capture.d.ts +88 -16
  112. package/dist/facade/simulate-capture.js +279 -153
  113. package/dist/facade/simulate-capture.js.map +1 -1
  114. package/dist/facade/simulate-display-view.d.ts +3 -2
  115. package/dist/facade/simulate-display-view.js +22 -12
  116. package/dist/facade/simulate-display-view.js.map +1 -1
  117. package/dist/gpu/chart-composite-gpu.js +1 -3
  118. package/dist/gpu/chart-composite-gpu.js.map +1 -1
  119. package/dist/gpu/chart-radiance-gpu.js +1 -5
  120. package/dist/gpu/chart-radiance-gpu.js.map +1 -1
  121. package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
  122. package/dist/gpu/display-view-quality-gpu.js +4 -8
  123. package/dist/gpu/display-view-quality-gpu.js.map +1 -1
  124. package/dist/gpu/display-view-speed-gpu.js +3 -25
  125. package/dist/gpu/display-view-speed-gpu.js.map +1 -1
  126. package/dist/gpu/sensor-stage-gpu.js +1 -5
  127. package/dist/gpu/sensor-stage-gpu.js.map +1 -1
  128. package/dist/gpu/webgpu-runtime.d.ts +2 -0
  129. package/dist/gpu/webgpu-runtime.js +3 -0
  130. package/dist/gpu/webgpu-runtime.js.map +1 -1
  131. package/dist/index.d.ts +11 -1
  132. package/dist/index.js +8 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/motion/camera-rotation.js +1 -6
  135. package/dist/motion/camera-rotation.js.map +1 -1
  136. package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
  137. package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
  138. package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
  139. package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
  140. package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
  141. package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
  142. package/dist/motion/capture-rotation-trajectory.js +2 -17
  143. package/dist/motion/capture-rotation-trajectory.js.map +1 -1
  144. package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
  145. package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
  146. package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
  147. package/dist/motion/extended-object-projection.js +5 -40
  148. package/dist/motion/extended-object-projection.js.map +1 -1
  149. package/dist/optics/aperture-diameter.d.ts +47 -0
  150. package/dist/optics/aperture-diameter.js +50 -0
  151. package/dist/optics/aperture-diameter.js.map +1 -0
  152. package/dist/optics/atmospheric-haze.js +1 -7
  153. package/dist/optics/atmospheric-haze.js.map +1 -1
  154. package/dist/optics/brown-conrady-distortion.js +1 -7
  155. package/dist/optics/brown-conrady-distortion.js.map +1 -1
  156. package/dist/optics/complex-pupil-psf.d.ts +1 -0
  157. package/dist/optics/complex-pupil-psf.js +2 -84
  158. package/dist/optics/complex-pupil-psf.js.map +1 -1
  159. package/dist/optics/detail-limit.d.ts +182 -0
  160. package/dist/optics/detail-limit.js +336 -0
  161. package/dist/optics/detail-limit.js.map +1 -0
  162. package/dist/optics/focus-state.js +1 -11
  163. package/dist/optics/focus-state.js.map +1 -1
  164. package/dist/optics/front-of-lens-filter.d.ts +5 -0
  165. package/dist/optics/front-of-lens-filter.js +3 -65
  166. package/dist/optics/front-of-lens-filter.js.map +1 -1
  167. package/dist/optics/generic-lens-psf.d.ts +18 -2
  168. package/dist/optics/generic-lens-psf.js +25 -2
  169. package/dist/optics/generic-lens-psf.js.map +1 -1
  170. package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
  171. package/dist/optics/generic-nd-filter-presets.js +48 -0
  172. package/dist/optics/generic-nd-filter-presets.js.map +1 -0
  173. package/dist/optics/illumination-vignetting.js +1 -6
  174. package/dist/optics/illumination-vignetting.js.map +1 -1
  175. package/dist/optics/lens-psf-profile.d.ts +4 -1
  176. package/dist/optics/lens-psf-profile.js +12 -111
  177. package/dist/optics/lens-psf-profile.js.map +1 -1
  178. package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
  179. package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
  180. package/dist/optics/pupil-vignetting.js +1 -7
  181. package/dist/optics/pupil-vignetting.js.map +1 -1
  182. package/dist/optics/radial-distortion.js +1 -6
  183. package/dist/optics/radial-distortion.js.map +1 -1
  184. package/dist/optics/scene-to-sensor-irradiance.d.ts +13 -0
  185. package/dist/optics/scene-to-sensor-irradiance.js +11 -96
  186. package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
  187. package/dist/optics/stray-light.d.ts +1 -0
  188. package/dist/optics/stray-light.js +1 -1
  189. package/dist/optics/stray-light.js.map +1 -1
  190. package/dist/optics/zernike-wavefront.js +1 -7
  191. package/dist/optics/zernike-wavefront.js.map +1 -1
  192. package/dist/output/capture-geometry.js +1 -8
  193. package/dist/output/capture-geometry.js.map +1 -1
  194. package/dist/output/crop-to-match-focal-length.d.ts +62 -0
  195. package/dist/output/crop-to-match-focal-length.js +63 -0
  196. package/dist/output/crop-to-match-focal-length.js.map +1 -0
  197. package/dist/output/developed-lens-corrections.d.ts +62 -0
  198. package/dist/output/developed-lens-corrections.js +135 -0
  199. package/dist/output/developed-lens-corrections.js.map +1 -0
  200. package/dist/output/generic-lens-corrections.d.ts +5 -7
  201. package/dist/output/generic-lens-corrections.js +11 -10
  202. package/dist/output/generic-lens-corrections.js.map +1 -1
  203. package/dist/output/geometric-transforms.js +1 -4
  204. package/dist/output/geometric-transforms.js.map +1 -1
  205. package/dist/output/lens-corrections.d.ts +12 -2
  206. package/dist/output/lens-corrections.js +22 -7
  207. package/dist/output/lens-corrections.js.map +1 -1
  208. package/dist/output/native-capture-sdr.d.ts +2 -2
  209. package/dist/output/native-capture-sdr.js +3 -2
  210. package/dist/output/native-capture-sdr.js.map +1 -1
  211. package/dist/output/print-contrast-reference.js +1 -1
  212. package/dist/output/print-contrast-reference.js.map +1 -1
  213. package/dist/output/print-size-blur-noise.d.ts +110 -0
  214. package/dist/output/print-size-blur-noise.js +138 -0
  215. package/dist/output/print-size-blur-noise.js.map +1 -0
  216. package/dist/processing/development-detail.d.ts +29 -0
  217. package/dist/processing/development-detail.js +128 -107
  218. package/dist/processing/development-detail.js.map +1 -1
  219. package/dist/schema/illumination-temporal.js +3 -72
  220. package/dist/schema/illumination-temporal.js.map +1 -1
  221. package/dist/schema/illumination.d.ts +1 -0
  222. package/dist/schema/illumination.js +2 -65
  223. package/dist/schema/illumination.js.map +1 -1
  224. package/dist/schema/scene-radiance-temporal.js +2 -14
  225. package/dist/schema/scene-radiance-temporal.js.map +1 -1
  226. package/dist/schema/scene-radiance.js +2 -60
  227. package/dist/schema/scene-radiance.js.map +1 -1
  228. package/dist/schema/validation.d.ts +2 -0
  229. package/dist/schema/validation.js +2 -17
  230. package/dist/schema/validation.js.map +1 -1
  231. package/dist/sensor/accumulated-charge.js +2 -59
  232. package/dist/sensor/accumulated-charge.js.map +1 -1
  233. package/dist/sensor/architecture.js +1 -16
  234. package/dist/sensor/architecture.js.map +1 -1
  235. package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
  236. package/dist/sensor/camera-saturation-capacity.js +3 -55
  237. package/dist/sensor/camera-saturation-capacity.js.map +1 -1
  238. package/dist/sensor/capture-color-sampling-binding.js +1 -26
  239. package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
  240. package/dist/sensor/capture-mode-timing.js +1 -39
  241. package/dist/sensor/capture-mode-timing.js.map +1 -1
  242. package/dist/sensor/capture-mode.js +1 -23
  243. package/dist/sensor/capture-mode.js.map +1 -1
  244. package/dist/sensor/color-sampling.js +1 -26
  245. package/dist/sensor/color-sampling.js.map +1 -1
  246. package/dist/sensor/constant-rate-temporal-integration.js +2 -46
  247. package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
  248. package/dist/sensor/dark-current.js +2 -45
  249. package/dist/sensor/dark-current.js.map +1 -1
  250. package/dist/sensor/eqe-electron-rate.js +2 -41
  251. package/dist/sensor/eqe-electron-rate.js.map +1 -1
  252. package/dist/sensor/exposure-window.d.ts +7 -0
  253. package/dist/sensor/exposure-window.js +9 -24
  254. package/dist/sensor/exposure-window.js.map +1 -1
  255. package/dist/sensor/iso-gain.js +1 -7
  256. package/dist/sensor/iso-gain.js.map +1 -1
  257. package/dist/sensor/iso-signal-chain.js +1 -43
  258. package/dist/sensor/iso-signal-chain.js.map +1 -1
  259. package/dist/sensor/optical-stack.js +1 -25
  260. package/dist/sensor/optical-stack.js.map +1 -1
  261. package/dist/sensor/photon-energy.js +1 -26
  262. package/dist/sensor/photon-energy.js.map +1 -1
  263. package/dist/sensor/physical-charge-capacity.js +3 -77
  264. package/dist/sensor/physical-charge-capacity.js.map +1 -1
  265. package/dist/sensor/radiometry-readiness.js +2 -23
  266. package/dist/sensor/radiometry-readiness.js.map +1 -1
  267. package/dist/sensor/raw-readout.d.ts +3 -0
  268. package/dist/sensor/raw-readout.js +4 -66
  269. package/dist/sensor/raw-readout.js.map +1 -1
  270. package/dist/sensor/raw-reconstruction.js +2 -64
  271. package/dist/sensor/raw-reconstruction.js.map +1 -1
  272. package/dist/sensor/readout-exposure-linkage.js +1 -9
  273. package/dist/sensor/readout-exposure-linkage.js.map +1 -1
  274. package/dist/sensor/readout-timing.js +4 -79
  275. package/dist/sensor/readout-timing.js.map +1 -1
  276. package/dist/sensor/response-application-compatibility.d.ts +2 -0
  277. package/dist/sensor/response-application-compatibility.js +4 -35
  278. package/dist/sensor/response-application-compatibility.js.map +1 -1
  279. package/dist/sensor/response-operating-range.d.ts +1 -0
  280. package/dist/sensor/response-operating-range.js +3 -79
  281. package/dist/sensor/response-operating-range.js.map +1 -1
  282. package/dist/sensor/responsivity-photocurrent.js +4 -114
  283. package/dist/sensor/responsivity-photocurrent.js.map +1 -1
  284. package/dist/sensor/sampling-aperture.js +1 -25
  285. package/dist/sensor/sampling-aperture.js.map +1 -1
  286. package/dist/sensor/sensor-characteristics.d.ts +137 -0
  287. package/dist/sensor/sensor-characteristics.js +115 -0
  288. package/dist/sensor/sensor-characteristics.js.map +1 -0
  289. package/dist/sensor/spatial-sample-reduction.js +3 -24
  290. package/dist/sensor/spatial-sample-reduction.js.map +1 -1
  291. package/dist/sensor/spatial-sampling-quadrature.js +1 -3
  292. package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
  293. package/dist/sensor/spatio-spectral-reduction.js +1 -18
  294. package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
  295. package/dist/sensor/spectral-coverage.d.ts +10 -1
  296. package/dist/sensor/spectral-coverage.js +1 -1
  297. package/dist/sensor/spectral-coverage.js.map +1 -1
  298. package/dist/sensor/spectral-quadrature.js +3 -41
  299. package/dist/sensor/spectral-quadrature.js.map +1 -1
  300. package/dist/sensor/spectral-response.js +1 -47
  301. package/dist/sensor/spectral-response.js.map +1 -1
  302. package/dist/sensor/temporal-photo-signal.d.ts +3 -0
  303. package/dist/sensor/temporal-photo-signal.js +5 -2
  304. package/dist/sensor/temporal-photo-signal.js.map +1 -1
  305. package/dist/stabilization/camera-shake.js +1 -6
  306. package/dist/stabilization/camera-shake.js.map +1 -1
  307. package/dist/stabilization/system.d.ts +9 -0
  308. package/dist/stabilization/system.js +7 -86
  309. package/dist/stabilization/system.js.map +1 -1
  310. package/docs/AGENT_GUIDE.md +5 -0
  311. package/docs/API_REFERENCE.md +116 -3
  312. package/docs/QUICK_START.md +178 -14
  313. package/docs/USAGE.md +111 -3
  314. package/docs/api/capture-native-raw-dng.md +6 -0
  315. package/docs/api/core-version.md +1 -1
  316. package/docs/api/equipment-generic-lens-catalogue.md +7 -2
  317. package/docs/api/exports.json +203 -3
  318. package/docs/api/exposure-filtered-exposure-time.md +105 -0
  319. package/docs/api/facade-develop-joined-parts.md +32 -0
  320. package/docs/api/facade-display-view-gpu.md +5 -2
  321. package/docs/api/facade-fast-methods.md +91 -0
  322. package/docs/api/facade-simulate-capture.md +72 -16
  323. package/docs/api/facade-simulate-display-view.md +3 -2
  324. package/docs/api/optics-aperture-diameter.md +51 -0
  325. package/docs/api/optics-detail-limit.md +203 -0
  326. package/docs/api/optics-generic-nd-filter-presets.md +34 -0
  327. package/docs/api/optics-lens-psf-profile.md +3 -1
  328. package/docs/api/output-crop-to-match-focal-length.md +67 -0
  329. package/docs/api/output-developed-lens-corrections.md +12 -0
  330. package/docs/api/output-generic-lens-corrections.md +3 -10
  331. package/docs/api/output-lens-corrections.md +11 -1
  332. package/docs/api/output-print-size-blur-noise.md +115 -0
  333. package/docs/api/sensor-sensor-characteristics.md +105 -0
  334. package/llms.txt +5 -0
  335. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/exposure/flash.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Manual flash and flash sync.\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock.\n * - Ordinary front- or rear-curtain sync needs a real interval when the whole frame is open at once.\n * - High-speed sync (HSS; schema 0.2.0 sync profiles) is separate: a near-continuous burst that\n * covers the travelling shutter slit (resolveHighSpeedFlashSync).\n * - TTL pre-flash power and guide-number relations are in flash-ttl.ts.\n * Source brightness, optical transport and sensor integration have their own contracts.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n ResolvedReleaseFrame\n} from \"../capture/release-sequence.js\";\nimport {\n parseSceneIlluminationProfile,\n type SceneIlluminationProfile,\n type SceneIlluminationSource\n} from \"../schema/illumination.js\";\nimport {\n parseSceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalWaveformSample\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputObject, requireInputKeys, rejectUnknownFields } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const MANUAL_FLASH_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const FLASH_SYNC_CAPABILITY_SCHEMA_VERSION =\n \"0.1.0\" as const;\n/** Sync-capability schema that may declare high-speed sync (a fast pulse train that acts as continuous light). */\nexport const FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION =\n \"0.2.0\" as const;\n/** Model identity of the pulsed quasi-continuous high-speed-sync burst. */\nexport const HIGH_SPEED_SYNC_MODEL = /* @__PURE__ */ Object.freeze({\n id: \"flash-hss-quasi-continuous-burst\",\n version: \"1.0.0\"\n} as const);\n\nexport type ManualFlashSyncMode =\n | \"front-curtain\"\n | \"rear-curtain\";\n\nexport type RequestedFlashSyncMode =\n | ManualFlashSyncMode\n | \"high-speed-sync\";\n\nexport interface ManualFlashPulseProfile {\n waveformId: string;\n scientificStatus: \"approximation\";\n supportDurationSeconds: number;\n interpolation: \"piecewise-linear\";\n samples:\n readonly SceneIlluminationTemporalWaveformSample[];\n normalization:\n \"relative-peak-one\";\n evidence:\n readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ManualFlashProfile {\n schemaVersion:\n typeof MANUAL_FLASH_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n sourceTemplate:\n Omit<\n SceneIlluminationSource,\n \"enabled\" |\n \"temporalBehavior\"\n >;\n pulse:\n ManualFlashPulseProfile;\n outputControl: {\n kind:\n \"relative-linear-source-scale\";\n scale: number;\n flashExposureCompensationStops:\n 0;\n };\n ttlModeled: false;\n highSpeedSyncModeled: false;\n recycleBehaviorModeled: false;\n redEyePreflashModeled: false;\n modelingLightModeled: false;\n afAssistModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface FlashSyncCapabilityProfile {\n schemaVersion:\n | typeof FLASH_SYNC_CAPABILITY_SCHEMA_VERSION\n | typeof FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n timingProfileId: string;\n supportedOrdinarySyncModes:\n readonly ManualFlashSyncMode[];\n /** Schema 0.1.0 is always false; schema 0.2.0 may declare HSS with {@link highSpeedSync}. */\n highSpeedSyncSupported: boolean;\n /** Present exactly when highSpeedSyncSupported is true (schema 0.2.0). */\n highSpeedSync?: {\n /**\n * η: energy of one full-power high-speed-sync burst, as a fraction of one full-power ordinary\n * pulse, in (0, 1]. The caller declares it from evidence (capacitor and thermal limits). It is\n * never inferred.\n */\n burstEnergyFractionOfFullPulse: number;\n evidence: readonly EvidenceProvenance[];\n };\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ResolveManualFlashSyncInput {\n flashEnabled: boolean;\n flashProfile:\n ManualFlashProfile;\n syncCapabilities:\n FlashSyncCapabilityProfile;\n timing:\n ResolvedCaptureModeTiming;\n syncMode:\n RequestedFlashSyncMode;\n releaseFrame?:\n ResolvedReleaseFrame;\n}\n\nexport interface ResolvedManualFlashSync {\n flashEnabled: boolean;\n flashProfileId: string;\n flashProfileVersion: string;\n sourceId: string;\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId:\n string;\n syncMode:\n RequestedFlashSyncMode;\n syncStatus:\n | \"disabled\"\n | \"ordinary-sync-resolved\";\n timeReference:\n \"first-opening-boundary-phase\";\n wholeActiveFrameOpenInterval:\n {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n pulseSupportDurationSeconds:\n number;\n pulseStartSecondsFromCaptureReference:\n number | null;\n pulseEndSecondsFromCaptureReference:\n number | null;\n waveformTimeZeroSecondsFromCaptureReference:\n number | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n number;\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n number;\n }\n | null;\n hssModeled: false;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n whiteBalanceModified: false;\n focusModified: false;\n exposureSettingsModified: false;\n driveModeModified: false;\n supportStateModified: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\n/** Fields of a resolved sync (ordinary or HSS) needed to register a flash overlay. */\nexport type FlashOverlaySyncRegistration = Pick<\n ResolvedManualFlashSync,\n | \"flashEnabled\"\n | \"flashProfileId\"\n | \"flashProfileVersion\"\n | \"sourceId\"\n | \"waveformTimeZeroSecondsFromCaptureReference\"\n | \"evidence\"\n>;\n\nexport interface CreateManualFlashIlluminationOverlayInput {\n baseIlluminationProfile:\n SceneIlluminationProfile;\n baseTemporalProfile?:\n SceneIlluminationTemporalProfile;\n flashProfile:\n ManualFlashProfile;\n resolvedSync:\n FlashOverlaySyncRegistration;\n illuminationProfileId: string;\n temporalProfileId: string;\n}\n\nexport interface ManualFlashIlluminationOverlay {\n flashApplied: boolean;\n illuminationProfile:\n SceneIlluminationProfile;\n temporalProfile:\n SceneIlluminationTemporalProfile | null;\n sourceId: string;\n waveformId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n sourceMagnitudeAppliedBySceneTransport:\n true;\n materialTransportOwnedBySceneRadiance:\n true;\n visibilityOwnedBySceneRadiance:\n true;\n indirectTransportOwnedBySceneRadiance:\n true;\n postRenderBrightnessMultiplierUsed:\n false;\n whiteBalanceModified: false;\n ambientMeteringModified: false;\n ttlMeteringIncluded: false;\n ambientTemporalBehaviorPreserved:\n true;\n}\n\nconst ORDINARY_SYNC_MODES =\n new Set<ManualFlashSyncMode>([\n \"front-curtain\",\n \"rear-curtain\"\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 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 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 parsePulseSamples(\n value: unknown,\n supportDurationSeconds:\n number,\n path: string\n): readonly SceneIlluminationTemporalWaveformSample[] {\n if (\n !Array.isArray(value) ||\n value.length < 2\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must contain at least two waveform samples.\"\n );\n }\n const samples =\n value.map((entry, index) => {\n const samplePath =\n path +\n \"[\" +\n index +\n \"]\";\n const record =\n requireRecord(\n entry,\n samplePath, [\"timeSecondsFromWaveformReference\", \"relativeMagnitudeMultiplier\"]\n );\n const time =\n requireFinite(\n record\n .timeSecondsFromWaveformReference,\n samplePath +\n \".timeSecondsFromWaveformReference\"\n );\n const magnitude =\n requireFinite(\n record\n .relativeMagnitudeMultiplier,\n samplePath +\n \".relativeMagnitudeMultiplier\"\n );\n if (\n time < 0 ||\n time >\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n samplePath +\n \".timeSecondsFromWaveformReference must lie within the declared pulse support.\"\n );\n }\n if (magnitude < 0) {\n throw new InvalidConfigurationError(\n samplePath +\n \".relativeMagnitudeMultiplier must be nonnegative.\"\n );\n }\n return {\n timeSecondsFromWaveformReference:\n time,\n relativeMagnitudeMultiplier:\n magnitude\n };\n });\n\n for (\n let index = 1;\n index < samples.length;\n index += 1\n ) {\n if (\n !(\n samples[index]!\n .timeSecondsFromWaveformReference >\n samples[index - 1]!\n .timeSecondsFromWaveformReference\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \" times must be strictly increasing.\"\n );\n }\n }\n if (\n samples[0]!\n .timeSecondsFromWaveformReference !==\n 0 ||\n samples[\n samples.length - 1\n ]!\n .timeSecondsFromWaveformReference !==\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must start at waveform time 0 and end exactly at supportDurationSeconds.\"\n );\n }\n const peak =\n Math.max(\n ...samples.map(\n (sample) =>\n sample\n .relativeMagnitudeMultiplier\n )\n );\n if (\n Math.abs(peak - 1) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" peak relative magnitude must equal one for relative-peak-one normalization.\"\n );\n }\n\n return samples;\n}\n\nfunction validateSourceTemplate(\n sourceTemplate:\n ManualFlashProfile[\"sourceTemplate\"]\n): ManualFlashProfile[\"sourceTemplate\"] {\n requireInputObject(sourceTemplate, \"manualFlashProfile.sourceTemplate\");\n const probe =\n parseSceneIlluminationProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n \"manual-flash-source-validation\",\n sceneId:\n \"manual-flash-source-validation\",\n evidence:\n sourceTemplate.evidence,\n sources: [{\n ...sourceTemplate,\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n }],\n sceneRadianceCalculated:\n false,\n materialResponseApplied:\n false,\n visibilityEvaluated:\n false,\n indirectTransportEvaluated:\n false,\n fluorescenceModeled:\n false,\n volumetricTransportModeled:\n false,\n polarizationModeled:\n false\n });\n const source =\n probe.sources[0];\n if (source === undefined) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.sourceTemplate must produce one valid illumination source.\"\n );\n }\n return {\n sourceId:\n source.sourceId,\n family:\n source.family,\n geometry:\n source.geometry,\n magnitude:\n source.magnitude,\n spectrum:\n source.spectrum,\n evidence:\n source.evidence,\n ...(source.limitations ===\n undefined\n ? {}\n : {\n limitations:\n source.limitations\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns ManualFlashProfile. 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 parseManualFlashProfile(\n value: unknown\n): ManualFlashProfile {\n const record =\n requireRecord(\n value,\n \"manualFlashProfile\", [\"schemaVersion\", \"pulse\", \"outputControl\", \"profileId\", \"profileVersion\", \"sourceTemplate\", \"evidence\", \"limitations\", \"ttlModeled\", \"highSpeedSyncModeled\", \"recycleBehaviorModeled\", \"redEyePreflashModeled\", \"modelingLightModeled\", \"afAssistModeled\"]\n );\n if (\n record.schemaVersion !==\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'manualFlashProfile.schemaVersion must be \"' +\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n for (\n const [key, expected] of [\n [\"ttlModeled\", false],\n [\"highSpeedSyncModeled\", false],\n [\"recycleBehaviorModeled\", false],\n [\"redEyePreflashModeled\", false],\n [\"modelingLightModeled\", false],\n [\"afAssistModeled\", false]\n ] as const\n ) {\n if (record[key] !== expected) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n const pulse =\n requireRecord(\n record.pulse,\n \"manualFlashProfile.pulse\", [\"supportDurationSeconds\", \"scientificStatus\", \"interpolation\", \"normalization\", \"waveformId\", \"samples\", \"evidence\", \"limitations\"]\n );\n const supportDurationSeconds =\n requirePositiveFinite(\n pulse.supportDurationSeconds,\n \"manualFlashProfile.pulse.supportDurationSeconds\"\n );\n if (\n pulse.scientificStatus !==\n \"approximation\" ||\n pulse.interpolation !==\n \"piecewise-linear\" ||\n pulse.normalization !==\n \"relative-peak-one\"\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.pulse scientificStatus/interpolation/normalization is invalid.\"\n );\n }\n\n const output =\n requireRecord(\n record.outputControl,\n \"manualFlashProfile.outputControl\", [\"kind\", \"flashExposureCompensationStops\", \"scale\"]\n );\n if (\n output.kind !==\n \"relative-linear-source-scale\" ||\n output\n .flashExposureCompensationStops !==\n 0\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.outputControl must use relative-linear-source-scale with zero flash exposure compensation in the manual-only schema.\"\n );\n }\n\n return {\n schemaVersion:\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"manualFlashProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"manualFlashProfile.profileVersion\"\n ),\n sourceTemplate:\n validateSourceTemplate(\n record.sourceTemplate as\n ManualFlashProfile[\"sourceTemplate\"]\n ),\n pulse: {\n waveformId:\n requireNonEmptyString(\n pulse.waveformId,\n \"manualFlashProfile.pulse.waveformId\"\n ),\n scientificStatus:\n \"approximation\",\n supportDurationSeconds,\n interpolation:\n \"piecewise-linear\",\n samples:\n parsePulseSamples(\n pulse.samples,\n supportDurationSeconds,\n \"manualFlashProfile.pulse.samples\"\n ),\n normalization:\n \"relative-peak-one\",\n evidence:\n parseEvidenceList(\n pulse.evidence,\n \"manualFlashProfile.pulse.evidence\"\n ),\n limitations:\n parseLimitations(\n pulse.limitations,\n \"manualFlashProfile.pulse.limitations\"\n )\n },\n outputControl: {\n kind:\n \"relative-linear-source-scale\",\n scale:\n requirePositiveFinite(\n output.scale,\n \"manualFlashProfile.outputControl.scale\"\n ),\n flashExposureCompensationStops:\n 0\n },\n ttlModeled: false,\n highSpeedSyncModeled: false,\n recycleBehaviorModeled:\n false,\n redEyePreflashModeled:\n false,\n modelingLightModeled:\n false,\n afAssistModeled: false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"manualFlashProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"manualFlashProfile.limitations\"\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns FlashSyncCapabilityProfile. 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 parseFlashSyncCapabilityProfile(\n value: unknown\n): FlashSyncCapabilityProfile {\n const record =\n requireRecord(\n value,\n \"flashSyncCapabilityProfile\", [\"schemaVersion\", \"highSpeedSyncSupported\", \"ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed\", \"highSpeedSync\", \"supportedOrdinarySyncModes\", \"profileId\", \"profileVersion\", \"captureModeId\", \"timingProfileId\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION &&\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'flashSyncCapabilityProfile.schemaVersion must be \"' +\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION +\n '\" or \"' +\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION +\n '\".'\n );\n }\n const hssSchema =\n record.schemaVersion ===\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n if (\n (hssSchema\n ? typeof record.highSpeedSyncSupported !==\n \"boolean\"\n : record.highSpeedSyncSupported !==\n false) ||\n record\n .ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed !==\n true\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile schema 0.1.0 supports ordinary whole-frame sync only and must not claim HSS.\"\n );\n }\n let highSpeedSync:\n FlashSyncCapabilityProfile[\"highSpeedSync\"];\n if (record.highSpeedSyncSupported === true) {\n const hss = requireRecord(\n record.highSpeedSync,\n \"flashSyncCapabilityProfile.highSpeedSync\", [\"burstEnergyFractionOfFullPulse\", \"evidence\"]\n );\n const fraction = requirePositiveFinite(\n hss.burstEnergyFractionOfFullPulse,\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse\"\n );\n if (fraction > 1) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse must be at most 1.\"\n );\n }\n highSpeedSync = {\n burstEnergyFractionOfFullPulse:\n fraction,\n evidence: parseEvidenceList(\n hss.evidence,\n \"flashSyncCapabilityProfile.highSpeedSync.evidence\"\n )\n };\n } else if (\n record.highSpeedSync !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync must be omitted when HSS is unsupported.\"\n );\n }\n if (\n !Array.isArray(\n record.supportedOrdinarySyncModes\n ) ||\n record\n .supportedOrdinarySyncModes\n .length === 0\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must be a non-empty array.\"\n );\n }\n const modes =\n record\n .supportedOrdinarySyncModes\n .map((entry, index) => {\n if (\n typeof entry !==\n \"string\" ||\n !ORDINARY_SYNC_MODES.has(\n entry as ManualFlashSyncMode\n )\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes[\" +\n index +\n \"] is invalid.\"\n );\n }\n return entry as\n ManualFlashSyncMode;\n });\n if (\n new Set(modes).size !==\n modes.length\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must not contain duplicates.\"\n );\n }\n\n return {\n schemaVersion: hssSchema\n ? FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n : FLASH_SYNC_CAPABILITY_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"flashSyncCapabilityProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"flashSyncCapabilityProfile.profileVersion\"\n ),\n captureModeId:\n requireNonEmptyString(\n record.captureModeId,\n \"flashSyncCapabilityProfile.captureModeId\"\n ),\n timingProfileId:\n requireNonEmptyString(\n record.timingProfileId,\n \"flashSyncCapabilityProfile.timingProfileId\"\n ),\n supportedOrdinarySyncModes:\n modes,\n highSpeedSyncSupported:\n highSpeedSync !== undefined,\n ...(highSpeedSync === undefined\n ? {}\n : { highSpeedSync }),\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"flashSyncCapabilityProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"flashSyncCapabilityProfile.limitations\"\n )\n };\n}\n\n/**\n * Shape guard for the resolved capture-mode timing record read by the flash sync functions: every\n * nested object read below must be an object, so a malformed record fails with\n * InvalidConfigurationError instead of a raw TypeError. Values are checked where they are used.\n */\nfunction requireTimingRecordShape(timing: unknown, path: string): void {\n requireInputObject(timing, path);\n const record = timing as Record<string, unknown>;\n if (!Array.isArray(record.evidence)) throw new InvalidConfigurationError(path + \".evidence must be an array.\");\n requireInputObject(record.exposureWindows, path + \".exposureWindows\");\n const windows = record.exposureWindows as Record<string, unknown>;\n requireInputObject(windows.nominalExposureDurationSeconds, path + \".exposureWindows.nominalExposureDurationSeconds\");\n requireInputObject(windows.localExposureDurationRangeSeconds, path + \".exposureWindows.localExposureDurationRangeSeconds\");\n for (const boundary of [\"opening\", \"closing\"] as const) {\n requireInputObject(windows[boundary], path + \".exposureWindows.\" + boundary);\n const schedule = (windows[boundary] as Record<string, unknown>).schedule;\n requireInputObject(schedule, path + \".exposureWindows.\" + boundary + \".schedule\");\n if ((schedule as Record<string, unknown>).kind !== \"simultaneous\") {\n requireInputObject((schedule as Record<string, unknown>).traversalDurationSeconds, path + \".exposureWindows.\" + boundary + \".schedule.traversalDurationSeconds\");\n }\n }\n}\n\nfunction wholeFrameOpenInterval(\n timing:\n ResolvedCaptureModeTiming\n): {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n} {\n const opening =\n timing.exposureWindows.opening\n .schedule;\n const latestOpening =\n opening.kind ===\n \"simultaneous\"\n ? 0\n : opening\n .traversalDurationSeconds\n .value;\n const earliestClosing =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const duration =\n earliestClosing -\n latestOpening;\n return {\n startSecondsFromCaptureReference:\n latestOpening,\n endSecondsFromCaptureReference:\n earliestClosing,\n durationSeconds:\n Math.max(0, duration)\n };\n}\n\nfunction validateReleaseBinding(\n release:\n ResolvedReleaseFrame,\n timing:\n ResolvedCaptureModeTiming\n): void {\n requireInputObject(release, \"releaseFrame\");\n requireInputObject(release.exposure, \"releaseFrame.exposure\");\n const nominal =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const scale =\n Math.max(\n 1,\n Math.abs(nominal),\n Math.abs(\n release.exposure\n .shutterSeconds\n )\n );\n if (\n Math.abs(\n release.exposure\n .shutterSeconds -\n nominal\n ) >\n Number.EPSILON *\n 16 *\n scale\n ) {\n throw new InvalidScientificInputError(\n \"releaseFrame shutter duration must match the exposure duration of the capture-mode exposure-window timing.\"\n );\n }\n}\n\n/**\n * Places a declared ordinary flash pulse inside the actual interval when the whole frame is open, for\n * front- or rear-curtain sync. Otherwise returns a structured incompatibility.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - ResolveManualFlashSyncInput. See that type for coordinates, units and profile binding.\n * @returns ResolvedManualFlashSync. 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 resolveManualFlashSync(\n input:\n ResolveManualFlashSyncInput\n): ResolvedManualFlashSync {\n requireInputKeys(input, \"resolveManualFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"syncMode\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveManualFlashSync timing\");\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const capabilities =\n parseFlashSyncCapabilityProfile(\n input.syncCapabilities\n );\n\n if (\n capabilities.captureModeId !==\n input.timing.captureModeId ||\n capabilities.timingProfileId !==\n input.timing.timingProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (\n input.releaseFrame !==\n undefined\n ) {\n validateReleaseBinding(\n input.releaseFrame,\n input.timing\n );\n }\n\n const openInterval =\n wholeFrameOpenInterval(\n input.timing\n );\n const base = {\n flashProfileId:\n flash.profileId,\n flashProfileVersion:\n flash.profileVersion,\n sourceId:\n flash.sourceTemplate.sourceId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n syncCapabilityProfileId:\n capabilities.profileId,\n syncMode:\n input.syncMode,\n timeReference:\n \"first-opening-boundary-phase\" as const,\n wholeActiveFrameOpenInterval:\n openInterval,\n pulseSupportDurationSeconds:\n flash.pulse\n .supportDurationSeconds,\n hssModeled: false as const,\n ttlModeled: false as const,\n sensorReadoutTimingUsedAsExposureTiming:\n false as const,\n whiteBalanceModified:\n false as const,\n focusModified: false as const,\n exposureSettingsModified:\n false as const,\n driveModeModified:\n false as const,\n supportStateModified:\n false as const,\n evidence: [\n ...flash.evidence,\n ...capabilities.evidence,\n ...input.timing.evidence\n ],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"Ordinary flash synchronization is registered to exposure-boundary timing, never sensor data-readout timing.\",\n \"Schema 0.1.0 does not model HSS, TTL/preflash metering, recycle/thermal limits, red-eye preflash, modeling lights, AF-assist or branded flash protocols.\"\n ]\n };\n\n if (!input.flashEnabled) {\n return {\n flashEnabled: false,\n ...base,\n syncStatus:\n \"disabled\",\n pulseStartSecondsFromCaptureReference:\n null,\n pulseEndSecondsFromCaptureReference:\n null,\n waveformTimeZeroSecondsFromCaptureReference:\n null,\n releaseFrameBinding:\n null\n };\n }\n\n if (\n input.syncMode ===\n \"high-speed-sync\"\n ) {\n throw new InvalidScientificInputError(\n \"High-speed sync is not an ordinary sync mode; ordinary single-pulse flash cannot be used as an HSS substitute. Use resolveHighSpeedFlashSync with an HSS-capable sync profile.\"\n );\n }\n if (\n !capabilities\n .supportedOrdinarySyncModes\n .includes(\n input.syncMode\n )\n ) {\n throw new InvalidScientificInputError(\n \"Requested ordinary flash sync mode is not supported by the capability profile.\"\n );\n }\n if (\n openInterval.durationSeconds <=\n 0\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary one-pulse flash cannot uniformly expose the active frame because the exposure-window timing has no whole-frame-open interval.\"\n );\n }\n if (\n flash.pulse\n .supportDurationSeconds >\n openInterval.durationSeconds\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary flash pulse support does not fit inside the whole-active-frame-open interval.\"\n );\n }\n\n const pulseStart =\n input.syncMode ===\n \"front-curtain\"\n ? openInterval\n .startSecondsFromCaptureReference\n : openInterval\n .endSecondsFromCaptureReference -\n flash.pulse\n .supportDurationSeconds;\n const pulseEnd =\n pulseStart +\n flash.pulse\n .supportDurationSeconds;\n\n const releaseBinding =\n input.releaseFrame ===\n undefined\n ? null\n : {\n sequenceId:\n input.releaseFrame\n .sequenceId,\n releaseFrameId:\n input.releaseFrame\n .releaseFrameId,\n frameIndex:\n input.releaseFrame\n .frameIndex,\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseStart,\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseEnd\n };\n\n return {\n flashEnabled: true,\n ...base,\n syncStatus:\n \"ordinary-sync-resolved\",\n pulseStartSecondsFromCaptureReference:\n pulseStart,\n pulseEndSecondsFromCaptureReference:\n pulseEnd,\n waveformTimeZeroSecondsFromCaptureReference:\n pulseStart,\n releaseFrameBinding:\n releaseBinding\n };\n}\n\nfunction scaledFlashSource(\n flash:\n ManualFlashProfile\n): SceneIlluminationSource {\n const template =\n flash.sourceTemplate;\n const magnitude =\n template.magnitude;\n if (\n magnitude.kind !==\n \"relative-linear-scale\"\n ) {\n throw new InvalidScientificInputError(\n \"Manual flash schema 0.1.0 relative output control requires a relative-linear-scale illumination source magnitude; calibrated physical flash energy belongs to a later profile.\"\n );\n }\n\n return {\n ...template,\n magnitude: {\n ...magnitude,\n scale:\n magnitude.scale *\n flash.outputControl.scale\n },\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n };\n}\n\n/**\n * Builds a temporal illumination overlay from the resolved manual pulse. The identity of the base\n * ambient light source is kept.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - CreateManualFlashIlluminationOverlayInput. See that type for coordinates, units and profile binding.\n * @returns ManualFlashIlluminationOverlay. 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 createManualFlashIlluminationOverlay(\n input:\n CreateManualFlashIlluminationOverlayInput\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createManualFlashIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"resolvedSync\", \"illuminationProfileId\", \"temporalProfileId\"]);\n const base =\n parseSceneIlluminationProfile(\n input\n .baseIlluminationProfile\n );\n const baseTemporal =\n input.baseTemporalProfile ===\n undefined\n ? null\n : parseSceneIlluminationTemporalProfile(\n input.baseTemporalProfile\n );\n if (\n baseTemporal !== null &&\n (\n baseTemporal.sceneId !==\n base.sceneId ||\n baseTemporal\n .illuminationProfileId !==\n base.profileId\n )\n ) {\n throw new InvalidScientificInputError(\n \"baseTemporalProfile must exactly match the base illumination profile scene/profile identities.\"\n );\n }\n\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const sync =\n input.resolvedSync;\n requireInputObject(sync, \"createManualFlashIlluminationOverlay resolvedSync\");\n if (!Array.isArray(sync.evidence)) throw new InvalidConfigurationError(\"createManualFlashIlluminationOverlay resolvedSync.evidence must be an array.\");\n\n if (\n sync.flashProfileId !==\n flash.profileId ||\n sync.flashProfileVersion !==\n flash.profileVersion ||\n sync.sourceId !==\n flash.sourceTemplate.sourceId\n ) {\n throw new InvalidScientificInputError(\n \"Resolved flash sync identity must match the manual flash profile.\"\n );\n }\n if (\n base.sources.some(\n (source) =>\n source.sourceId ===\n flash.sourceTemplate\n .sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Flash sourceId must be unique within the base illumination profile.\"\n );\n }\n\n if (!sync.flashEnabled) {\n return {\n flashApplied: false,\n illuminationProfile:\n base,\n temporalProfile:\n baseTemporal,\n sourceId:\n flash.sourceTemplate\n .sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n }\n if (\n sync\n .waveformTimeZeroSecondsFromCaptureReference ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Enabled flash sync must provide an authoritative waveform time-zero registration.\"\n );\n }\n\n const flashSource =\n scaledFlashSource(\n flash\n );\n const illumination =\n parseSceneIlluminationProfile({\n ...base,\n profileId:\n requireNonEmptyString(\n input.illuminationProfileId,\n \"illuminationProfileId\"\n ),\n sources: [\n ...base.sources,\n flashSource\n ]\n });\n\n const temporal =\n parseSceneIlluminationTemporalProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n requireNonEmptyString(\n input.temporalProfileId,\n \"temporalProfileId\"\n ),\n sceneId:\n illumination.sceneId,\n illuminationProfileId:\n illumination.profileId,\n evidence: [\n ...(baseTemporal?.evidence ?? []),\n ...flash.evidence,\n ...sync.evidence\n ],\n waveforms: [\n ...(baseTemporal?.waveforms ?? []),\n {\n waveformId:\n flash.pulse.waveformId,\n kind:\n \"aperiodic-relative-multiplier\",\n timeUnit: \"s\",\n scientificStatus:\n \"approximation\",\n uncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Manual flash pulse timing/shape is an explicit approximation.\"\n },\n evidence:\n flash.pulse.evidence,\n interpolation:\n \"piecewise-linear\",\n samples:\n flash.pulse.samples,\n outsideSupportBehavior:\n \"zero\"\n }\n ],\n sourceBindings: [\n ...(baseTemporal?.sourceBindings ?? []),\n {\n bindingId:\n flash.profileId +\n \":sync\",\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n captureTimeReference:\n \"first-opening-boundary-phase\",\n waveformTimeZeroSecondsFromCaptureReference:\n sync\n .waveformTimeZeroSecondsFromCaptureReference,\n scientificStatus:\n \"approximation\",\n timingUncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Schema 0.1.0 uses ideal deterministic flash trigger registration within the declared exposure-window schedule.\"\n },\n evidence:\n sync.evidence\n }\n ],\n baseIlluminationProfileRemainsAuthoritative:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n automaticExposurePolicyIncluded:\n false\n });\n\n return {\n flashApplied: true,\n illuminationProfile:\n illumination,\n temporalProfile:\n temporal,\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n}\n\nexport interface ResolveHighSpeedFlashSyncInput {\n flashEnabled: boolean;\n /** Ordinary full-power pulse definition; its integral defines the full-power pulse energy. */\n flashProfile: ManualFlashProfile;\n /** Schema 0.2.0 profile with highSpeedSyncSupported true. */\n syncCapabilities: FlashSyncCapabilityProfile;\n timing: ResolvedCaptureModeTiming;\n /** Commanded output as a fraction of full power, (0, 1]. */\n powerFraction: number;\n releaseFrame?: ResolvedReleaseFrame;\n}\n\nexport interface ResolvedHighSpeedFlashSync extends FlashOverlaySyncRegistration {\n modelId: typeof HIGH_SPEED_SYNC_MODEL.id;\n modelVersion: typeof HIGH_SPEED_SYNC_MODEL.version;\n syncMode: \"high-speed-sync\";\n syncStatus: \"disabled\" | \"high-speed-sync-resolved\";\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId: string;\n timeReference: \"first-opening-boundary-phase\";\n powerFraction: number;\n /** η from the sync capability profile. */\n burstEnergyFractionOfFullPulse: number;\n /** ∫ pulse(t) dt of the declared ordinary pulse, whose relative peak is 1 (relative multiplier · s). */\n singlePulseIntegratedRelativeSeconds: number;\n /** D: burst support covering the first line opening to the last line closing. */\n burstStartSecondsFromCaptureReference: number;\n burstEndSecondsFromCaptureReference: number;\n burstDurationSeconds: number;\n /** Local (slit) exposure durations t_e over the active frame. */\n localExposureDurationRangeSeconds: { minimum: number; maximum: number };\n /** Flash energy each line receives relative to one ordinary pulse at the same power: η·t_e/D. */\n energyFractionOfSinglePulseRange: { minimum: number; maximum: number };\n /** Effective guide-number factor relative to the same-power ordinary pulse: √(η·t_e/D). */\n guideNumberFactorRange: { minimum: number; maximum: number };\n uniformAcrossActiveFrame: boolean;\n /** The rectangular high-speed-sync burst, written as a manual pulse profile for the illumination overlay. */\n burstFlashProfile: ManualFlashProfile | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtBurstStart: number;\n sceneTimeSecondsFromSequenceStartAtBurstEnd: number;\n }\n | null;\n hssModeled: true;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming: false;\n limitations: readonly string[];\n}\n\nfunction integratePulse(samples: readonly SceneIlluminationTemporalWaveformSample[]): number {\n let area = 0;\n for (let index = 1; index < samples.length; index += 1) {\n const a = samples[index - 1]!, b = samples[index]!;\n area += (b.timeSecondsFromWaveformReference - a.timeSecondsFromWaveformReference) *\n (a.relativeMagnitudeMultiplier + b.relativeMagnitudeMultiplier) / 2;\n }\n return area;\n}\n\n/**\n * Resolves high-speed (focal-plane) sync (HSS): a fast pulse train that acts as continuous light and\n * covers the whole travelling-slit exposure.\n *\n * At shutter speeds faster than the ordinary sync limit, the shutter's opening and closing edges\n * cross the frame as a slit, and the whole frame is never open at once. A single short pulse would\n * light only a band.\n *\n * HSS instead fires a rapid pulse train. It behaves like constant output P over the burst D, from\n * the first line opening to the last line closing. Each line collects P·t_e over its slit time t_e.\n * - The burst energy is E_burst = η·p·E_pulse. η comes from the sync profile, p is the power\n * fraction and E_pulse is the energy of an ordinary full-power pulse.\n * - So P = E_burst/D, and each line receives η·p·E_pulse·t_e/D.\n * - Exposure ∝ GN² (inverse-square law, GN = d·N). So, relative to an ordinary pulse at the same\n * power, the effective guide number is GN_HSS/GN = √(η·t_e/D).\n * Shortening t_e by one stop therefore costs half a stop of guide number.\n *\n * Approximations: the pulse train is treated as continuous (pulse period ≪ t_e). Recycle and thermal\n * limits are folded into η. Front/rear-curtain placement does not apply, because the burst covers\n * the whole exposure.\n * @see docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md#high-speed-sync\n */\nexport function resolveHighSpeedFlashSync(input: ResolveHighSpeedFlashSyncInput): ResolvedHighSpeedFlashSync {\n requireInputKeys(input, \"resolveHighSpeedFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"powerFraction\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveHighSpeedFlashSync timing\");\n const flash = parseManualFlashProfile(input.flashProfile);\n const capabilities = parseFlashSyncCapabilityProfile(input.syncCapabilities);\n if (capabilities.captureModeId !== input.timing.captureModeId || capabilities.timingProfileId !== input.timing.timingProfileId) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (!capabilities.highSpeedSyncSupported || capabilities.highSpeedSync === undefined) {\n throw new InvalidScientificInputError(\"The flash sync capability profile does not declare high-speed sync.\");\n }\n const power = input.powerFraction;\n if (typeof power !== \"number\" || !Number.isFinite(power) || power <= 0 || power > 1) {\n throw new InvalidScientificInputError(\"HSS powerFraction must lie in (0, 1].\");\n }\n if (input.releaseFrame !== undefined) validateReleaseBinding(input.releaseFrame, input.timing);\n\n const windows = input.timing.exposureWindows;\n const closing = windows.closing.schedule;\n const burstEnd = windows.nominalExposureDurationSeconds.value +\n (closing.kind === \"simultaneous\" ? 0 : closing.traversalDurationSeconds.value);\n const eta = capabilities.highSpeedSync.burstEnergyFractionOfFullPulse;\n const local = windows.localExposureDurationRangeSeconds;\n const fraction = { minimum: eta * local.minimum / burstEnd, maximum: eta * local.maximum / burstEnd };\n const pulseEnergy = integratePulse(flash.pulse.samples);\n const burstFlashProfile: ManualFlashProfile = {\n ...flash,\n pulse: {\n ...flash.pulse,\n waveformId: flash.pulse.waveformId + \"-hss-burst\",\n supportDurationSeconds: burstEnd,\n samples: [\n { timeSecondsFromWaveformReference: 0, relativeMagnitudeMultiplier: 1 },\n { timeSecondsFromWaveformReference: burstEnd, relativeMagnitudeMultiplier: 1 }\n ],\n limitations: [...flash.pulse.limitations,\n \"Quasi-continuous HSS burst: the pulse train is approximated by constant output over the burst support.\"]\n },\n outputControl: { ...flash.outputControl, scale: flash.outputControl.scale * power * eta * pulseEnergy / burstEnd }\n };\n const enabled = input.flashEnabled;\n return {\n modelId: HIGH_SPEED_SYNC_MODEL.id,\n modelVersion: HIGH_SPEED_SYNC_MODEL.version,\n flashEnabled: enabled,\n flashProfileId: flash.profileId,\n flashProfileVersion: flash.profileVersion,\n sourceId: flash.sourceTemplate.sourceId,\n syncMode: \"high-speed-sync\",\n syncStatus: enabled ? \"high-speed-sync-resolved\" : \"disabled\",\n captureModeId: input.timing.captureModeId,\n timingProfileId: input.timing.timingProfileId,\n syncCapabilityProfileId: capabilities.profileId,\n timeReference: \"first-opening-boundary-phase\",\n powerFraction: power,\n burstEnergyFractionOfFullPulse: eta,\n singlePulseIntegratedRelativeSeconds: pulseEnergy,\n burstStartSecondsFromCaptureReference: 0,\n burstEndSecondsFromCaptureReference: burstEnd,\n burstDurationSeconds: burstEnd,\n localExposureDurationRangeSeconds: { minimum: local.minimum, maximum: local.maximum },\n energyFractionOfSinglePulseRange: fraction,\n guideNumberFactorRange: { minimum: Math.sqrt(fraction.minimum), maximum: Math.sqrt(fraction.maximum) },\n uniformAcrossActiveFrame: local.minimum === local.maximum,\n burstFlashProfile: enabled ? burstFlashProfile : null,\n waveformTimeZeroSecondsFromCaptureReference: enabled ? 0 : null,\n releaseFrameBinding: !enabled || input.releaseFrame === undefined ? null : {\n sequenceId: input.releaseFrame.sequenceId,\n releaseFrameId: input.releaseFrame.releaseFrameId,\n frameIndex: input.releaseFrame.frameIndex,\n sceneTimeSecondsFromSequenceStartAtBurstStart: input.releaseFrame.sceneTimeSecondsFromSequenceStart,\n sceneTimeSecondsFromSequenceStartAtBurstEnd: input.releaseFrame.sceneTimeSecondsFromSequenceStart + burstEnd\n },\n hssModeled: true,\n ttlModeled: false,\n sensorReadoutTimingUsedAsExposureTiming: false,\n evidence: [...flash.evidence, ...capabilities.evidence, ...capabilities.highSpeedSync.evidence, ...input.timing.evidence],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"HSS burst is registered to exposure-boundary timing (first line opening to last line closing), never sensor data-readout timing.\",\n \"Pulse-train ripple, recycle/thermal limits beyond the declared burst energy fraction and branded flash protocols are not modeled.\"\n ]\n };\n}\n\n/**\n * Registers a resolved high-speed-sync burst as a temporal illumination overlay: a rectangular\n * waveform over [0, D]. Each line then collects the burst over its own local exposure window.\n */\nexport function createHighSpeedSyncIlluminationOverlay(\n input: Omit<CreateManualFlashIlluminationOverlayInput, \"resolvedSync\"> & { resolvedSync: ResolvedHighSpeedFlashSync }\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createHighSpeedSyncIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"illuminationProfileId\", \"temporalProfileId\", \"resolvedSync\"]);\n requireInputObject(input.resolvedSync, \"createHighSpeedSyncIlluminationOverlay resolvedSync\");\n return createManualFlashIlluminationOverlay({ ...input,\n flashProfile: input.resolvedSync.burstFlashProfile ?? input.flashProfile });\n}\n"]}
1
+ {"version":3,"file":"flash.js","sourceRoot":"","sources":["../../src/exposure/flash.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Manual flash and flash sync.\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock.\n * - Ordinary front- or rear-curtain sync needs a real interval when the whole frame is open at once.\n * - High-speed sync (HSS; schema 0.2.0 sync profiles) is separate: a near-continuous burst that\n * covers the travelling shutter slit (resolveHighSpeedFlashSync).\n * - TTL pre-flash power and guide-number relations are in flash-ttl.ts.\n * Source brightness, optical transport and sensor integration have their own contracts.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n ResolvedReleaseFrame\n} from \"../capture/release-sequence.js\";\nimport {\n parseSceneIlluminationProfile,\n type SceneIlluminationProfile,\n type SceneIlluminationSource\n} from \"../schema/illumination.js\";\nimport {\n parseSceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalProfile,\n type SceneIlluminationTemporalWaveformSample\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ResolvedCaptureModeTiming\n} from \"../sensor/capture-mode-timing.js\";\nimport { requireInputObject, requireInputKeys, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireConfigFinite as requireFinite, parseConfigLimitations as parseLimitations, requireConfigFiniteAboveZero as requirePositiveFinite } from \"../core/record-validation.js\";\n\nexport const MANUAL_FLASH_PROFILE_SCHEMA_VERSION =\n \"0.1.0\" as const;\nexport const FLASH_SYNC_CAPABILITY_SCHEMA_VERSION =\n \"0.1.0\" as const;\n/** Sync-capability schema that may declare high-speed sync (a fast pulse train that acts as continuous light). */\nexport const FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION =\n \"0.2.0\" as const;\n/** Model identity of the pulsed quasi-continuous high-speed-sync burst. */\nexport const HIGH_SPEED_SYNC_MODEL = /* @__PURE__ */ Object.freeze({\n id: \"flash-hss-quasi-continuous-burst\",\n version: \"1.0.0\"\n} as const);\n\nexport type ManualFlashSyncMode =\n | \"front-curtain\"\n | \"rear-curtain\";\n\nexport type RequestedFlashSyncMode =\n | ManualFlashSyncMode\n | \"high-speed-sync\";\n\nexport interface ManualFlashPulseProfile {\n waveformId: string;\n scientificStatus: \"approximation\";\n supportDurationSeconds: number;\n interpolation: \"piecewise-linear\";\n samples:\n readonly SceneIlluminationTemporalWaveformSample[];\n normalization:\n \"relative-peak-one\";\n evidence:\n readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ManualFlashProfile {\n schemaVersion:\n typeof MANUAL_FLASH_PROFILE_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n sourceTemplate:\n Omit<\n SceneIlluminationSource,\n \"enabled\" |\n \"temporalBehavior\"\n >;\n pulse:\n ManualFlashPulseProfile;\n outputControl: {\n kind:\n \"relative-linear-source-scale\";\n scale: number;\n flashExposureCompensationStops:\n 0;\n };\n ttlModeled: false;\n highSpeedSyncModeled: false;\n recycleBehaviorModeled: false;\n redEyePreflashModeled: false;\n modelingLightModeled: false;\n afAssistModeled: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface FlashSyncCapabilityProfile {\n schemaVersion:\n | typeof FLASH_SYNC_CAPABILITY_SCHEMA_VERSION\n | typeof FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n profileId: string;\n profileVersion: string;\n captureModeId: string;\n timingProfileId: string;\n supportedOrdinarySyncModes:\n readonly ManualFlashSyncMode[];\n /** Schema 0.1.0 is always false; schema 0.2.0 may declare HSS with {@link highSpeedSync}. */\n highSpeedSyncSupported: boolean;\n /** Present exactly when highSpeedSyncSupported is true (schema 0.2.0). */\n highSpeedSync?: {\n /**\n * η: energy of one full-power high-speed-sync burst, as a fraction of one full-power ordinary\n * pulse, in (0, 1]. The caller declares it from evidence (capacitor and thermal limits). It is\n * never inferred.\n */\n burstEnergyFractionOfFullPulse: number;\n evidence: readonly EvidenceProvenance[];\n };\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\nexport interface ResolveManualFlashSyncInput {\n flashEnabled: boolean;\n flashProfile:\n ManualFlashProfile;\n syncCapabilities:\n FlashSyncCapabilityProfile;\n timing:\n ResolvedCaptureModeTiming;\n syncMode:\n RequestedFlashSyncMode;\n releaseFrame?:\n ResolvedReleaseFrame;\n}\n\nexport interface ResolvedManualFlashSync {\n flashEnabled: boolean;\n flashProfileId: string;\n flashProfileVersion: string;\n sourceId: string;\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId:\n string;\n syncMode:\n RequestedFlashSyncMode;\n syncStatus:\n | \"disabled\"\n | \"ordinary-sync-resolved\";\n timeReference:\n \"first-opening-boundary-phase\";\n wholeActiveFrameOpenInterval:\n {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n };\n pulseSupportDurationSeconds:\n number;\n pulseStartSecondsFromCaptureReference:\n number | null;\n pulseEndSecondsFromCaptureReference:\n number | null;\n waveformTimeZeroSecondsFromCaptureReference:\n number | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n number;\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n number;\n }\n | null;\n hssModeled: false;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming:\n false;\n whiteBalanceModified: false;\n focusModified: false;\n exposureSettingsModified: false;\n driveModeModified: false;\n supportStateModified: false;\n evidence: readonly EvidenceProvenance[];\n limitations: readonly string[];\n}\n\n/** Fields of a resolved sync (ordinary or HSS) needed to register a flash overlay. */\nexport type FlashOverlaySyncRegistration = Pick<\n ResolvedManualFlashSync,\n | \"flashEnabled\"\n | \"flashProfileId\"\n | \"flashProfileVersion\"\n | \"sourceId\"\n | \"waveformTimeZeroSecondsFromCaptureReference\"\n | \"evidence\"\n>;\n\nexport interface CreateManualFlashIlluminationOverlayInput {\n baseIlluminationProfile:\n SceneIlluminationProfile;\n baseTemporalProfile?:\n SceneIlluminationTemporalProfile;\n flashProfile:\n ManualFlashProfile;\n resolvedSync:\n FlashOverlaySyncRegistration;\n illuminationProfileId: string;\n temporalProfileId: string;\n}\n\nexport interface ManualFlashIlluminationOverlay {\n flashApplied: boolean;\n illuminationProfile:\n SceneIlluminationProfile;\n temporalProfile:\n SceneIlluminationTemporalProfile | null;\n sourceId: string;\n waveformId: string;\n timeReference:\n \"first-opening-boundary-phase\";\n sourceMagnitudeAppliedBySceneTransport:\n true;\n materialTransportOwnedBySceneRadiance:\n true;\n visibilityOwnedBySceneRadiance:\n true;\n indirectTransportOwnedBySceneRadiance:\n true;\n postRenderBrightnessMultiplierUsed:\n false;\n whiteBalanceModified: false;\n ambientMeteringModified: false;\n ttlMeteringIncluded: false;\n ambientTemporalBehaviorPreserved:\n true;\n}\n\nconst ORDINARY_SYNC_MODES =\n new Set<ManualFlashSyncMode>([\n \"front-curtain\",\n \"rear-curtain\"\n ]);\n\nfunction parsePulseSamples(\n value: unknown,\n supportDurationSeconds:\n number,\n path: string\n): readonly SceneIlluminationTemporalWaveformSample[] {\n if (\n !Array.isArray(value) ||\n value.length < 2\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must contain at least two waveform samples.\"\n );\n }\n const samples =\n value.map((entry, index) => {\n const samplePath =\n path +\n \"[\" +\n index +\n \"]\";\n const record =\n requireRecord(\n entry,\n samplePath, [\"timeSecondsFromWaveformReference\", \"relativeMagnitudeMultiplier\"]\n );\n const time =\n requireFinite(\n record\n .timeSecondsFromWaveformReference,\n samplePath +\n \".timeSecondsFromWaveformReference\"\n );\n const magnitude =\n requireFinite(\n record\n .relativeMagnitudeMultiplier,\n samplePath +\n \".relativeMagnitudeMultiplier\"\n );\n if (\n time < 0 ||\n time >\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n samplePath +\n \".timeSecondsFromWaveformReference must lie within the declared pulse support.\"\n );\n }\n if (magnitude < 0) {\n throw new InvalidConfigurationError(\n samplePath +\n \".relativeMagnitudeMultiplier must be nonnegative.\"\n );\n }\n return {\n timeSecondsFromWaveformReference:\n time,\n relativeMagnitudeMultiplier:\n magnitude\n };\n });\n\n for (\n let index = 1;\n index < samples.length;\n index += 1\n ) {\n if (\n !(\n samples[index]!\n .timeSecondsFromWaveformReference >\n samples[index - 1]!\n .timeSecondsFromWaveformReference\n )\n ) {\n throw new InvalidConfigurationError(\n path +\n \" times must be strictly increasing.\"\n );\n }\n }\n if (\n samples[0]!\n .timeSecondsFromWaveformReference !==\n 0 ||\n samples[\n samples.length - 1\n ]!\n .timeSecondsFromWaveformReference !==\n supportDurationSeconds\n ) {\n throw new InvalidConfigurationError(\n path +\n \" must start at waveform time 0 and end exactly at supportDurationSeconds.\"\n );\n }\n const peak =\n Math.max(\n ...samples.map(\n (sample) =>\n sample\n .relativeMagnitudeMultiplier\n )\n );\n if (\n Math.abs(peak - 1) >\n 1e-12\n ) {\n throw new InvalidConfigurationError(\n path +\n \" peak relative magnitude must equal one for relative-peak-one normalization.\"\n );\n }\n\n return samples;\n}\n\nfunction validateSourceTemplate(\n sourceTemplate:\n ManualFlashProfile[\"sourceTemplate\"]\n): ManualFlashProfile[\"sourceTemplate\"] {\n requireInputObject(sourceTemplate, \"manualFlashProfile.sourceTemplate\");\n const probe =\n parseSceneIlluminationProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n \"manual-flash-source-validation\",\n sceneId:\n \"manual-flash-source-validation\",\n evidence:\n sourceTemplate.evidence,\n sources: [{\n ...sourceTemplate,\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n }],\n sceneRadianceCalculated:\n false,\n materialResponseApplied:\n false,\n visibilityEvaluated:\n false,\n indirectTransportEvaluated:\n false,\n fluorescenceModeled:\n false,\n volumetricTransportModeled:\n false,\n polarizationModeled:\n false\n });\n const source =\n probe.sources[0];\n if (source === undefined) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.sourceTemplate must produce one valid illumination source.\"\n );\n }\n return {\n sourceId:\n source.sourceId,\n family:\n source.family,\n geometry:\n source.geometry,\n magnitude:\n source.magnitude,\n spectrum:\n source.spectrum,\n evidence:\n source.evidence,\n ...(source.limitations ===\n undefined\n ? {}\n : {\n limitations:\n source.limitations\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns ManualFlashProfile. 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 parseManualFlashProfile(\n value: unknown\n): ManualFlashProfile {\n const record =\n requireRecord(\n value,\n \"manualFlashProfile\", [\"schemaVersion\", \"pulse\", \"outputControl\", \"profileId\", \"profileVersion\", \"sourceTemplate\", \"evidence\", \"limitations\", \"ttlModeled\", \"highSpeedSyncModeled\", \"recycleBehaviorModeled\", \"redEyePreflashModeled\", \"modelingLightModeled\", \"afAssistModeled\"]\n );\n if (\n record.schemaVersion !==\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'manualFlashProfile.schemaVersion must be \"' +\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION +\n '\".'\n );\n }\n for (\n const [key, expected] of [\n [\"ttlModeled\", false],\n [\"highSpeedSyncModeled\", false],\n [\"recycleBehaviorModeled\", false],\n [\"redEyePreflashModeled\", false],\n [\"modelingLightModeled\", false],\n [\"afAssistModeled\", false]\n ] as const\n ) {\n if (record[key] !== expected) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.\" +\n key +\n \" must be false in schema 0.1.0.\"\n );\n }\n }\n\n const pulse =\n requireRecord(\n record.pulse,\n \"manualFlashProfile.pulse\", [\"supportDurationSeconds\", \"scientificStatus\", \"interpolation\", \"normalization\", \"waveformId\", \"samples\", \"evidence\", \"limitations\"]\n );\n const supportDurationSeconds =\n requirePositiveFinite(\n pulse.supportDurationSeconds,\n \"manualFlashProfile.pulse.supportDurationSeconds\"\n );\n if (\n pulse.scientificStatus !==\n \"approximation\" ||\n pulse.interpolation !==\n \"piecewise-linear\" ||\n pulse.normalization !==\n \"relative-peak-one\"\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.pulse scientificStatus/interpolation/normalization is invalid.\"\n );\n }\n\n const output =\n requireRecord(\n record.outputControl,\n \"manualFlashProfile.outputControl\", [\"kind\", \"flashExposureCompensationStops\", \"scale\"]\n );\n if (\n output.kind !==\n \"relative-linear-source-scale\" ||\n output\n .flashExposureCompensationStops !==\n 0\n ) {\n throw new InvalidConfigurationError(\n \"manualFlashProfile.outputControl must use relative-linear-source-scale with zero flash exposure compensation in the manual-only schema.\"\n );\n }\n\n return {\n schemaVersion:\n MANUAL_FLASH_PROFILE_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"manualFlashProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"manualFlashProfile.profileVersion\"\n ),\n sourceTemplate:\n validateSourceTemplate(\n record.sourceTemplate as\n ManualFlashProfile[\"sourceTemplate\"]\n ),\n pulse: {\n waveformId:\n requireNonEmptyString(\n pulse.waveformId,\n \"manualFlashProfile.pulse.waveformId\"\n ),\n scientificStatus:\n \"approximation\",\n supportDurationSeconds,\n interpolation:\n \"piecewise-linear\",\n samples:\n parsePulseSamples(\n pulse.samples,\n supportDurationSeconds,\n \"manualFlashProfile.pulse.samples\"\n ),\n normalization:\n \"relative-peak-one\",\n evidence:\n parseEvidenceList(\n pulse.evidence,\n \"manualFlashProfile.pulse.evidence\"\n ),\n limitations:\n parseLimitations(\n pulse.limitations,\n \"manualFlashProfile.pulse.limitations\"\n )\n },\n outputControl: {\n kind:\n \"relative-linear-source-scale\",\n scale:\n requirePositiveFinite(\n output.scale,\n \"manualFlashProfile.outputControl.scale\"\n ),\n flashExposureCompensationStops:\n 0\n },\n ttlModeled: false,\n highSpeedSyncModeled: false,\n recycleBehaviorModeled:\n false,\n redEyePreflashModeled:\n false,\n modelingLightModeled:\n false,\n afAssistModeled: false,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"manualFlashProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"manualFlashProfile.limitations\"\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 * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param value - unknown. Untrusted input; TypeScript types alone are not validation.\n * @returns FlashSyncCapabilityProfile. 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 parseFlashSyncCapabilityProfile(\n value: unknown\n): FlashSyncCapabilityProfile {\n const record =\n requireRecord(\n value,\n \"flashSyncCapabilityProfile\", [\"schemaVersion\", \"highSpeedSyncSupported\", \"ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed\", \"highSpeedSync\", \"supportedOrdinarySyncModes\", \"profileId\", \"profileVersion\", \"captureModeId\", \"timingProfileId\", \"evidence\", \"limitations\"]\n );\n if (\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION &&\n record.schemaVersion !==\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'flashSyncCapabilityProfile.schemaVersion must be \"' +\n FLASH_SYNC_CAPABILITY_SCHEMA_VERSION +\n '\" or \"' +\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION +\n '\".'\n );\n }\n const hssSchema =\n record.schemaVersion ===\n FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION;\n if (\n (hssSchema\n ? typeof record.highSpeedSyncSupported !==\n \"boolean\"\n : record.highSpeedSyncSupported !==\n false) ||\n record\n .ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed !==\n true\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile schema 0.1.0 supports ordinary whole-frame sync only and must not claim HSS.\"\n );\n }\n let highSpeedSync:\n FlashSyncCapabilityProfile[\"highSpeedSync\"];\n if (record.highSpeedSyncSupported === true) {\n const hss = requireRecord(\n record.highSpeedSync,\n \"flashSyncCapabilityProfile.highSpeedSync\", [\"burstEnergyFractionOfFullPulse\", \"evidence\"]\n );\n const fraction = requirePositiveFinite(\n hss.burstEnergyFractionOfFullPulse,\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse\"\n );\n if (fraction > 1) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync.burstEnergyFractionOfFullPulse must be at most 1.\"\n );\n }\n highSpeedSync = {\n burstEnergyFractionOfFullPulse:\n fraction,\n evidence: parseEvidenceList(\n hss.evidence,\n \"flashSyncCapabilityProfile.highSpeedSync.evidence\"\n )\n };\n } else if (\n record.highSpeedSync !==\n undefined\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.highSpeedSync must be omitted when HSS is unsupported.\"\n );\n }\n if (\n !Array.isArray(\n record.supportedOrdinarySyncModes\n ) ||\n record\n .supportedOrdinarySyncModes\n .length === 0\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must be a non-empty array.\"\n );\n }\n const modes =\n record\n .supportedOrdinarySyncModes\n .map((entry, index) => {\n if (\n typeof entry !==\n \"string\" ||\n !ORDINARY_SYNC_MODES.has(\n entry as ManualFlashSyncMode\n )\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes[\" +\n index +\n \"] is invalid.\"\n );\n }\n return entry as\n ManualFlashSyncMode;\n });\n if (\n new Set(modes).size !==\n modes.length\n ) {\n throw new InvalidConfigurationError(\n \"flashSyncCapabilityProfile.supportedOrdinarySyncModes must not contain duplicates.\"\n );\n }\n\n return {\n schemaVersion: hssSchema\n ? FLASH_SYNC_CAPABILITY_HSS_SCHEMA_VERSION\n : FLASH_SYNC_CAPABILITY_SCHEMA_VERSION,\n profileId:\n requireNonEmptyString(\n record.profileId,\n \"flashSyncCapabilityProfile.profileId\"\n ),\n profileVersion:\n requireNonEmptyString(\n record.profileVersion,\n \"flashSyncCapabilityProfile.profileVersion\"\n ),\n captureModeId:\n requireNonEmptyString(\n record.captureModeId,\n \"flashSyncCapabilityProfile.captureModeId\"\n ),\n timingProfileId:\n requireNonEmptyString(\n record.timingProfileId,\n \"flashSyncCapabilityProfile.timingProfileId\"\n ),\n supportedOrdinarySyncModes:\n modes,\n highSpeedSyncSupported:\n highSpeedSync !== undefined,\n ...(highSpeedSync === undefined\n ? {}\n : { highSpeedSync }),\n ordinarySyncRequiresWholeActiveFrameSimultaneouslyExposed:\n true,\n evidence:\n parseEvidenceList(\n record.evidence,\n \"flashSyncCapabilityProfile.evidence\"\n ),\n limitations:\n parseLimitations(\n record.limitations,\n \"flashSyncCapabilityProfile.limitations\"\n )\n };\n}\n\n/**\n * Shape guard for the resolved capture-mode timing record read by the flash sync functions: every\n * nested object read below must be an object, so a malformed record fails with\n * InvalidConfigurationError instead of a raw TypeError. Values are checked where they are used.\n */\nfunction requireTimingRecordShape(timing: unknown, path: string): void {\n requireInputObject(timing, path);\n const record = timing as Record<string, unknown>;\n if (!Array.isArray(record.evidence)) throw new InvalidConfigurationError(path + \".evidence must be an array.\");\n requireInputObject(record.exposureWindows, path + \".exposureWindows\");\n const windows = record.exposureWindows as Record<string, unknown>;\n requireInputObject(windows.nominalExposureDurationSeconds, path + \".exposureWindows.nominalExposureDurationSeconds\");\n requireInputObject(windows.localExposureDurationRangeSeconds, path + \".exposureWindows.localExposureDurationRangeSeconds\");\n for (const boundary of [\"opening\", \"closing\"] as const) {\n requireInputObject(windows[boundary], path + \".exposureWindows.\" + boundary);\n const schedule = (windows[boundary] as Record<string, unknown>).schedule;\n requireInputObject(schedule, path + \".exposureWindows.\" + boundary + \".schedule\");\n if ((schedule as Record<string, unknown>).kind !== \"simultaneous\") {\n requireInputObject((schedule as Record<string, unknown>).traversalDurationSeconds, path + \".exposureWindows.\" + boundary + \".schedule.traversalDurationSeconds\");\n }\n }\n}\n\nfunction wholeFrameOpenInterval(\n timing:\n ResolvedCaptureModeTiming\n): {\n startSecondsFromCaptureReference:\n number;\n endSecondsFromCaptureReference:\n number;\n durationSeconds: number;\n} {\n const opening =\n timing.exposureWindows.opening\n .schedule;\n const latestOpening =\n opening.kind ===\n \"simultaneous\"\n ? 0\n : opening\n .traversalDurationSeconds\n .value;\n const earliestClosing =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const duration =\n earliestClosing -\n latestOpening;\n return {\n startSecondsFromCaptureReference:\n latestOpening,\n endSecondsFromCaptureReference:\n earliestClosing,\n durationSeconds:\n Math.max(0, duration)\n };\n}\n\nfunction validateReleaseBinding(\n release:\n ResolvedReleaseFrame,\n timing:\n ResolvedCaptureModeTiming\n): void {\n requireInputObject(release, \"releaseFrame\");\n requireInputObject(release.exposure, \"releaseFrame.exposure\");\n const nominal =\n timing.exposureWindows\n .nominalExposureDurationSeconds\n .value;\n const scale =\n Math.max(\n 1,\n Math.abs(nominal),\n Math.abs(\n release.exposure\n .shutterSeconds\n )\n );\n if (\n Math.abs(\n release.exposure\n .shutterSeconds -\n nominal\n ) >\n Number.EPSILON *\n 16 *\n scale\n ) {\n throw new InvalidScientificInputError(\n \"releaseFrame shutter duration must match the exposure duration of the capture-mode exposure-window timing.\"\n );\n }\n}\n\n/**\n * Places a declared ordinary flash pulse inside the actual interval when the whole frame is open, for\n * front- or rear-curtain sync. Otherwise returns a structured incompatibility.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - ResolveManualFlashSyncInput. See that type for coordinates, units and profile binding.\n * @returns ResolvedManualFlashSync. 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 resolveManualFlashSync(\n input:\n ResolveManualFlashSyncInput\n): ResolvedManualFlashSync {\n requireInputKeys(input, \"resolveManualFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"syncMode\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveManualFlashSync timing\");\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const capabilities =\n parseFlashSyncCapabilityProfile(\n input.syncCapabilities\n );\n\n if (\n capabilities.captureModeId !==\n input.timing.captureModeId ||\n capabilities.timingProfileId !==\n input.timing.timingProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (\n input.releaseFrame !==\n undefined\n ) {\n validateReleaseBinding(\n input.releaseFrame,\n input.timing\n );\n }\n\n const openInterval =\n wholeFrameOpenInterval(\n input.timing\n );\n const base = {\n flashProfileId:\n flash.profileId,\n flashProfileVersion:\n flash.profileVersion,\n sourceId:\n flash.sourceTemplate.sourceId,\n captureModeId:\n input.timing.captureModeId,\n timingProfileId:\n input.timing.timingProfileId,\n syncCapabilityProfileId:\n capabilities.profileId,\n syncMode:\n input.syncMode,\n timeReference:\n \"first-opening-boundary-phase\" as const,\n wholeActiveFrameOpenInterval:\n openInterval,\n pulseSupportDurationSeconds:\n flash.pulse\n .supportDurationSeconds,\n hssModeled: false as const,\n ttlModeled: false as const,\n sensorReadoutTimingUsedAsExposureTiming:\n false as const,\n whiteBalanceModified:\n false as const,\n focusModified: false as const,\n exposureSettingsModified:\n false as const,\n driveModeModified:\n false as const,\n supportStateModified:\n false as const,\n evidence: [\n ...flash.evidence,\n ...capabilities.evidence,\n ...input.timing.evidence\n ],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"Ordinary flash synchronization is registered to exposure-boundary timing, never sensor data-readout timing.\",\n \"Schema 0.1.0 does not model HSS, TTL/preflash metering, recycle/thermal limits, red-eye preflash, modeling lights, AF-assist or branded flash protocols.\"\n ]\n };\n\n if (!input.flashEnabled) {\n return {\n flashEnabled: false,\n ...base,\n syncStatus:\n \"disabled\",\n pulseStartSecondsFromCaptureReference:\n null,\n pulseEndSecondsFromCaptureReference:\n null,\n waveformTimeZeroSecondsFromCaptureReference:\n null,\n releaseFrameBinding:\n null\n };\n }\n\n if (\n input.syncMode ===\n \"high-speed-sync\"\n ) {\n throw new InvalidScientificInputError(\n \"High-speed sync is not an ordinary sync mode; ordinary single-pulse flash cannot be used as an HSS substitute. Use resolveHighSpeedFlashSync with an HSS-capable sync profile.\"\n );\n }\n if (\n !capabilities\n .supportedOrdinarySyncModes\n .includes(\n input.syncMode\n )\n ) {\n throw new InvalidScientificInputError(\n \"Requested ordinary flash sync mode is not supported by the capability profile.\"\n );\n }\n if (\n openInterval.durationSeconds <=\n 0\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary one-pulse flash cannot uniformly expose the active frame because the exposure-window timing has no whole-frame-open interval.\"\n );\n }\n if (\n flash.pulse\n .supportDurationSeconds >\n openInterval.durationSeconds\n ) {\n throw new InvalidScientificInputError(\n \"Ordinary flash pulse support does not fit inside the whole-active-frame-open interval.\"\n );\n }\n\n const pulseStart =\n input.syncMode ===\n \"front-curtain\"\n ? openInterval\n .startSecondsFromCaptureReference\n : openInterval\n .endSecondsFromCaptureReference -\n flash.pulse\n .supportDurationSeconds;\n const pulseEnd =\n pulseStart +\n flash.pulse\n .supportDurationSeconds;\n\n const releaseBinding =\n input.releaseFrame ===\n undefined\n ? null\n : {\n sequenceId:\n input.releaseFrame\n .sequenceId,\n releaseFrameId:\n input.releaseFrame\n .releaseFrameId,\n frameIndex:\n input.releaseFrame\n .frameIndex,\n sceneTimeSecondsFromSequenceStartAtPulseStart:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseStart,\n sceneTimeSecondsFromSequenceStartAtPulseEnd:\n input.releaseFrame\n .sceneTimeSecondsFromSequenceStart +\n pulseEnd\n };\n\n return {\n flashEnabled: true,\n ...base,\n syncStatus:\n \"ordinary-sync-resolved\",\n pulseStartSecondsFromCaptureReference:\n pulseStart,\n pulseEndSecondsFromCaptureReference:\n pulseEnd,\n waveformTimeZeroSecondsFromCaptureReference:\n pulseStart,\n releaseFrameBinding:\n releaseBinding\n };\n}\n\nfunction scaledFlashSource(\n flash:\n ManualFlashProfile\n): SceneIlluminationSource {\n const template =\n flash.sourceTemplate;\n const magnitude =\n template.magnitude;\n if (\n magnitude.kind !==\n \"relative-linear-scale\"\n ) {\n throw new InvalidScientificInputError(\n \"Manual flash schema 0.1.0 relative output control requires a relative-linear-scale illumination source magnitude; calibrated physical flash energy belongs to a later profile.\"\n );\n }\n\n return {\n ...template,\n magnitude: {\n ...magnitude,\n scale:\n magnitude.scale *\n flash.outputControl.scale\n },\n enabled: true,\n temporalBehavior: {\n kind:\n \"time-invariant\"\n }\n };\n}\n\n/**\n * Builds a temporal illumination overlay from the resolved manual pulse. The identity of the base\n * ambient light source is kept.\n *\n * Manual flash is a relative light pulse added on top of the scene light, timed on the capture's\n * opening-reference clock. Ordinary front- or rear-curtain sync needs a real interval when the whole\n * frame is open at once. High-speed sync (HSS), TTL and flash metering are not handled here. Source\n * brightness, optical transport and sensor integration have their own contracts.\n * @param input - CreateManualFlashIlluminationOverlayInput. See that type for coordinates, units and profile binding.\n * @returns ManualFlashIlluminationOverlay. 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 createManualFlashIlluminationOverlay(\n input:\n CreateManualFlashIlluminationOverlayInput\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createManualFlashIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"resolvedSync\", \"illuminationProfileId\", \"temporalProfileId\"]);\n const base =\n parseSceneIlluminationProfile(\n input\n .baseIlluminationProfile\n );\n const baseTemporal =\n input.baseTemporalProfile ===\n undefined\n ? null\n : parseSceneIlluminationTemporalProfile(\n input.baseTemporalProfile\n );\n if (\n baseTemporal !== null &&\n (\n baseTemporal.sceneId !==\n base.sceneId ||\n baseTemporal\n .illuminationProfileId !==\n base.profileId\n )\n ) {\n throw new InvalidScientificInputError(\n \"baseTemporalProfile must exactly match the base illumination profile scene/profile identities.\"\n );\n }\n\n const flash =\n parseManualFlashProfile(\n input.flashProfile\n );\n const sync =\n input.resolvedSync;\n requireInputObject(sync, \"createManualFlashIlluminationOverlay resolvedSync\");\n if (!Array.isArray(sync.evidence)) throw new InvalidConfigurationError(\"createManualFlashIlluminationOverlay resolvedSync.evidence must be an array.\");\n\n if (\n sync.flashProfileId !==\n flash.profileId ||\n sync.flashProfileVersion !==\n flash.profileVersion ||\n sync.sourceId !==\n flash.sourceTemplate.sourceId\n ) {\n throw new InvalidScientificInputError(\n \"Resolved flash sync identity must match the manual flash profile.\"\n );\n }\n if (\n base.sources.some(\n (source) =>\n source.sourceId ===\n flash.sourceTemplate\n .sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Flash sourceId must be unique within the base illumination profile.\"\n );\n }\n\n if (!sync.flashEnabled) {\n return {\n flashApplied: false,\n illuminationProfile:\n base,\n temporalProfile:\n baseTemporal,\n sourceId:\n flash.sourceTemplate\n .sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n }\n if (\n sync\n .waveformTimeZeroSecondsFromCaptureReference ===\n null\n ) {\n throw new InvalidScientificInputError(\n \"Enabled flash sync must provide an authoritative waveform time-zero registration.\"\n );\n }\n\n const flashSource =\n scaledFlashSource(\n flash\n );\n const illumination =\n parseSceneIlluminationProfile({\n ...base,\n profileId:\n requireNonEmptyString(\n input.illuminationProfileId,\n \"illuminationProfileId\"\n ),\n sources: [\n ...base.sources,\n flashSource\n ]\n });\n\n const temporal =\n parseSceneIlluminationTemporalProfile({\n schemaVersion: \"0.1.0\",\n profileId:\n requireNonEmptyString(\n input.temporalProfileId,\n \"temporalProfileId\"\n ),\n sceneId:\n illumination.sceneId,\n illuminationProfileId:\n illumination.profileId,\n evidence: [\n ...(baseTemporal?.evidence ?? []),\n ...flash.evidence,\n ...sync.evidence\n ],\n waveforms: [\n ...(baseTemporal?.waveforms ?? []),\n {\n waveformId:\n flash.pulse.waveformId,\n kind:\n \"aperiodic-relative-multiplier\",\n timeUnit: \"s\",\n scientificStatus:\n \"approximation\",\n uncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Manual flash pulse timing/shape is an explicit approximation.\"\n },\n evidence:\n flash.pulse.evidence,\n interpolation:\n \"piecewise-linear\",\n samples:\n flash.pulse.samples,\n outsideSupportBehavior:\n \"zero\"\n }\n ],\n sourceBindings: [\n ...(baseTemporal?.sourceBindings ?? []),\n {\n bindingId:\n flash.profileId +\n \":sync\",\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n captureTimeReference:\n \"first-opening-boundary-phase\",\n waveformTimeZeroSecondsFromCaptureReference:\n sync\n .waveformTimeZeroSecondsFromCaptureReference,\n scientificStatus:\n \"approximation\",\n timingUncertainty: {\n kind:\n \"not-quantified\",\n limitation:\n \"Schema 0.1.0 uses ideal deterministic flash trigger registration within the declared exposure-window schedule.\"\n },\n evidence:\n sync.evidence\n }\n ],\n baseIlluminationProfileRemainsAuthoritative:\n true,\n sensorReadoutTimingUsedAsExposureTiming:\n false,\n automaticExposurePolicyIncluded:\n false\n });\n\n return {\n flashApplied: true,\n illuminationProfile:\n illumination,\n temporalProfile:\n temporal,\n sourceId:\n flashSource.sourceId,\n waveformId:\n flash.pulse.waveformId,\n timeReference:\n \"first-opening-boundary-phase\",\n sourceMagnitudeAppliedBySceneTransport:\n true,\n materialTransportOwnedBySceneRadiance:\n true,\n visibilityOwnedBySceneRadiance:\n true,\n indirectTransportOwnedBySceneRadiance:\n true,\n postRenderBrightnessMultiplierUsed:\n false,\n whiteBalanceModified:\n false,\n ambientMeteringModified:\n false,\n ambientTemporalBehaviorPreserved:\n true,\n ttlMeteringIncluded:\n false\n };\n}\n\nexport interface ResolveHighSpeedFlashSyncInput {\n flashEnabled: boolean;\n /** Ordinary full-power pulse definition; its integral defines the full-power pulse energy. */\n flashProfile: ManualFlashProfile;\n /** Schema 0.2.0 profile with highSpeedSyncSupported true. */\n syncCapabilities: FlashSyncCapabilityProfile;\n timing: ResolvedCaptureModeTiming;\n /** Commanded output as a fraction of full power, (0, 1]. */\n powerFraction: number;\n releaseFrame?: ResolvedReleaseFrame;\n}\n\nexport interface ResolvedHighSpeedFlashSync extends FlashOverlaySyncRegistration {\n modelId: typeof HIGH_SPEED_SYNC_MODEL.id;\n modelVersion: typeof HIGH_SPEED_SYNC_MODEL.version;\n syncMode: \"high-speed-sync\";\n syncStatus: \"disabled\" | \"high-speed-sync-resolved\";\n captureModeId: string;\n timingProfileId: string;\n syncCapabilityProfileId: string;\n timeReference: \"first-opening-boundary-phase\";\n powerFraction: number;\n /** η from the sync capability profile. */\n burstEnergyFractionOfFullPulse: number;\n /** ∫ pulse(t) dt of the declared ordinary pulse, whose relative peak is 1 (relative multiplier · s). */\n singlePulseIntegratedRelativeSeconds: number;\n /** D: burst support covering the first line opening to the last line closing. */\n burstStartSecondsFromCaptureReference: number;\n burstEndSecondsFromCaptureReference: number;\n burstDurationSeconds: number;\n /** Local (slit) exposure durations t_e over the active frame. */\n localExposureDurationRangeSeconds: { minimum: number; maximum: number };\n /** Flash energy each line receives relative to one ordinary pulse at the same power: η·t_e/D. */\n energyFractionOfSinglePulseRange: { minimum: number; maximum: number };\n /** Effective guide-number factor relative to the same-power ordinary pulse: √(η·t_e/D). */\n guideNumberFactorRange: { minimum: number; maximum: number };\n uniformAcrossActiveFrame: boolean;\n /** The rectangular high-speed-sync burst, written as a manual pulse profile for the illumination overlay. */\n burstFlashProfile: ManualFlashProfile | null;\n releaseFrameBinding:\n | {\n sequenceId: string;\n releaseFrameId: string;\n frameIndex: number;\n sceneTimeSecondsFromSequenceStartAtBurstStart: number;\n sceneTimeSecondsFromSequenceStartAtBurstEnd: number;\n }\n | null;\n hssModeled: true;\n ttlModeled: false;\n sensorReadoutTimingUsedAsExposureTiming: false;\n limitations: readonly string[];\n}\n\nfunction integratePulse(samples: readonly SceneIlluminationTemporalWaveformSample[]): number {\n let area = 0;\n for (let index = 1; index < samples.length; index += 1) {\n const a = samples[index - 1]!, b = samples[index]!;\n area += (b.timeSecondsFromWaveformReference - a.timeSecondsFromWaveformReference) *\n (a.relativeMagnitudeMultiplier + b.relativeMagnitudeMultiplier) / 2;\n }\n return area;\n}\n\n/**\n * Resolves high-speed (focal-plane) sync (HSS): a fast pulse train that acts as continuous light and\n * covers the whole travelling-slit exposure.\n *\n * At shutter speeds faster than the ordinary sync limit, the shutter's opening and closing edges\n * cross the frame as a slit, and the whole frame is never open at once. A single short pulse would\n * light only a band.\n *\n * HSS instead fires a rapid pulse train. It behaves like constant output P over the burst D, from\n * the first line opening to the last line closing. Each line collects P·t_e over its slit time t_e.\n * - The burst energy is E_burst = η·p·E_pulse. η comes from the sync profile, p is the power\n * fraction and E_pulse is the energy of an ordinary full-power pulse.\n * - So P = E_burst/D, and each line receives η·p·E_pulse·t_e/D.\n * - Exposure ∝ GN² (inverse-square law, GN = d·N). So, relative to an ordinary pulse at the same\n * power, the effective guide number is GN_HSS/GN = √(η·t_e/D).\n * Shortening t_e by one stop therefore costs half a stop of guide number.\n *\n * Approximations: the pulse train is treated as continuous (pulse period ≪ t_e). Recycle and thermal\n * limits are folded into η. Front/rear-curtain placement does not apply, because the burst covers\n * the whole exposure.\n * @see docs/SCENE_SENSOR_TEMPORAL_EXPOSURE.md#high-speed-sync\n */\nexport function resolveHighSpeedFlashSync(input: ResolveHighSpeedFlashSyncInput): ResolvedHighSpeedFlashSync {\n requireInputKeys(input, \"resolveHighSpeedFlashSync\", [\"flashEnabled\", \"flashProfile\", \"syncCapabilities\", \"timing\", \"powerFraction\", \"releaseFrame\"]);\n requireTimingRecordShape(input.timing, \"resolveHighSpeedFlashSync timing\");\n const flash = parseManualFlashProfile(input.flashProfile);\n const capabilities = parseFlashSyncCapabilityProfile(input.syncCapabilities);\n if (capabilities.captureModeId !== input.timing.captureModeId || capabilities.timingProfileId !== input.timing.timingProfileId) {\n throw new InvalidScientificInputError(\n \"Flash sync capability profile must exactly match the resolved capture-mode and timing-profile identities.\"\n );\n }\n if (!capabilities.highSpeedSyncSupported || capabilities.highSpeedSync === undefined) {\n throw new InvalidScientificInputError(\"The flash sync capability profile does not declare high-speed sync.\");\n }\n const power = input.powerFraction;\n if (typeof power !== \"number\" || !Number.isFinite(power) || power <= 0 || power > 1) {\n throw new InvalidScientificInputError(\"HSS powerFraction must lie in (0, 1].\");\n }\n if (input.releaseFrame !== undefined) validateReleaseBinding(input.releaseFrame, input.timing);\n\n const windows = input.timing.exposureWindows;\n const closing = windows.closing.schedule;\n const burstEnd = windows.nominalExposureDurationSeconds.value +\n (closing.kind === \"simultaneous\" ? 0 : closing.traversalDurationSeconds.value);\n const eta = capabilities.highSpeedSync.burstEnergyFractionOfFullPulse;\n const local = windows.localExposureDurationRangeSeconds;\n const fraction = { minimum: eta * local.minimum / burstEnd, maximum: eta * local.maximum / burstEnd };\n const pulseEnergy = integratePulse(flash.pulse.samples);\n const burstFlashProfile: ManualFlashProfile = {\n ...flash,\n pulse: {\n ...flash.pulse,\n waveformId: flash.pulse.waveformId + \"-hss-burst\",\n supportDurationSeconds: burstEnd,\n samples: [\n { timeSecondsFromWaveformReference: 0, relativeMagnitudeMultiplier: 1 },\n { timeSecondsFromWaveformReference: burstEnd, relativeMagnitudeMultiplier: 1 }\n ],\n limitations: [...flash.pulse.limitations,\n \"Quasi-continuous HSS burst: the pulse train is approximated by constant output over the burst support.\"]\n },\n outputControl: { ...flash.outputControl, scale: flash.outputControl.scale * power * eta * pulseEnergy / burstEnd }\n };\n const enabled = input.flashEnabled;\n return {\n modelId: HIGH_SPEED_SYNC_MODEL.id,\n modelVersion: HIGH_SPEED_SYNC_MODEL.version,\n flashEnabled: enabled,\n flashProfileId: flash.profileId,\n flashProfileVersion: flash.profileVersion,\n sourceId: flash.sourceTemplate.sourceId,\n syncMode: \"high-speed-sync\",\n syncStatus: enabled ? \"high-speed-sync-resolved\" : \"disabled\",\n captureModeId: input.timing.captureModeId,\n timingProfileId: input.timing.timingProfileId,\n syncCapabilityProfileId: capabilities.profileId,\n timeReference: \"first-opening-boundary-phase\",\n powerFraction: power,\n burstEnergyFractionOfFullPulse: eta,\n singlePulseIntegratedRelativeSeconds: pulseEnergy,\n burstStartSecondsFromCaptureReference: 0,\n burstEndSecondsFromCaptureReference: burstEnd,\n burstDurationSeconds: burstEnd,\n localExposureDurationRangeSeconds: { minimum: local.minimum, maximum: local.maximum },\n energyFractionOfSinglePulseRange: fraction,\n guideNumberFactorRange: { minimum: Math.sqrt(fraction.minimum), maximum: Math.sqrt(fraction.maximum) },\n uniformAcrossActiveFrame: local.minimum === local.maximum,\n burstFlashProfile: enabled ? burstFlashProfile : null,\n waveformTimeZeroSecondsFromCaptureReference: enabled ? 0 : null,\n releaseFrameBinding: !enabled || input.releaseFrame === undefined ? null : {\n sequenceId: input.releaseFrame.sequenceId,\n releaseFrameId: input.releaseFrame.releaseFrameId,\n frameIndex: input.releaseFrame.frameIndex,\n sceneTimeSecondsFromSequenceStartAtBurstStart: input.releaseFrame.sceneTimeSecondsFromSequenceStart,\n sceneTimeSecondsFromSequenceStartAtBurstEnd: input.releaseFrame.sceneTimeSecondsFromSequenceStart + burstEnd\n },\n hssModeled: true,\n ttlModeled: false,\n sensorReadoutTimingUsedAsExposureTiming: false,\n evidence: [...flash.evidence, ...capabilities.evidence, ...capabilities.highSpeedSync.evidence, ...input.timing.evidence],\n limitations: [\n ...flash.limitations,\n ...capabilities.limitations,\n \"HSS burst is registered to exposure-boundary timing (first line opening to last line closing), never sensor data-readout timing.\",\n \"Pulse-train ripple, recycle/thermal limits beyond the declared burst energy fraction and branded flash protocols are not modeled.\"\n ]\n };\n}\n\n/**\n * Registers a resolved high-speed-sync burst as a temporal illumination overlay: a rectangular\n * waveform over [0, D]. Each line then collects the burst over its own local exposure window.\n */\nexport function createHighSpeedSyncIlluminationOverlay(\n input: Omit<CreateManualFlashIlluminationOverlayInput, \"resolvedSync\"> & { resolvedSync: ResolvedHighSpeedFlashSync }\n): ManualFlashIlluminationOverlay {\n requireInputKeys(input, \"createHighSpeedSyncIlluminationOverlay\", [\"baseIlluminationProfile\", \"baseTemporalProfile\", \"flashProfile\", \"illuminationProfileId\", \"temporalProfileId\", \"resolvedSync\"]);\n requireInputObject(input.resolvedSync, \"createHighSpeedSyncIlluminationOverlay resolvedSync\");\n return createManualFlashIlluminationOverlay({ ...input,\n flashProfile: input.resolvedSync.burstFlashProfile ?? input.flashProfile });\n}\n"]}
@@ -17,32 +17,8 @@ import { InvalidConfigurationError } from "../core/configuration-error.js";
17
17
  import { parseEvidenceList } from "../core/evidence-provenance.js";
18
18
  import { InvalidScientificInputError } from "../core/validation.js";
19
19
  import { assessSceneMaterialResponseFidelity } from "../schema/scene-radiance.js";
20
- import { requireInputKeys, requireInputObject, rejectUnknownFields } from "../core/record-validation.js";
20
+ import { requireInputKeys, requireInputObject, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireInputFinite as requireFinite } from "../core/record-validation.js";
21
21
  export const SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION = "0.1.0";
22
- function requireRecord(value, path, allowedKeys) {
23
- if (typeof value !== "object" ||
24
- value === null ||
25
- Array.isArray(value)) {
26
- throw new InvalidConfigurationError(path + " must be an object.");
27
- }
28
- if (allowedKeys !== null)
29
- rejectUnknownFields(value, allowedKeys, path);
30
- return value;
31
- }
32
- function requireNonEmptyString(value, path) {
33
- if (typeof value !== "string" ||
34
- value.trim().length === 0) {
35
- throw new InvalidConfigurationError(path + " must be a non-empty string.");
36
- }
37
- return value.trim();
38
- }
39
- function requireFinite(value, path) {
40
- if (typeof value !== "number" ||
41
- !Number.isFinite(value)) {
42
- throw new InvalidScientificInputError(path + " must be finite.");
43
- }
44
- return value;
45
- }
46
22
  /**
47
23
  * Parses the declared approximation that turns renderer or provider scene data
48
24
  * into the single relative linear values the meter uses.
@@ -1 +1 @@
1
- {"version":3,"file":"metering-scene-radiance.js","sourceRoot":"","sources":["../../src/exposure/metering-scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Links scene radiance to metering.\n *\n * The profile parser reads the declared approximation that turns renderer or provider scene data into\n * the single relative linear values the meter uses. The profile does not support any claim of\n * calibrated luminance or of a spectral-to-photometric conversion.\n *\n * The sample-set function builds a set of relative pre-exposure meter samples tied to one validated\n * scene-radiance provider context. The caller or renderer still supplies the relative sample values.\n * This bridge only checks identity and timing. It does not convert spectral radiance into luminance,\n * and it does not define a calibrated meter spectral response.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n ResolvedCaptureGeometry\n} from \"../output/capture-geometry.js\";\nimport {\n assessSceneMaterialResponseFidelity,\n type SceneMaterialResponseProfile,\n type SceneRadianceProviderProfile\n} from \"../schema/scene-radiance.js\";\nimport type {\n SceneIlluminationProfile\n} from \"../schema/illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ExposureMeteringSampleSet,\n ExposureMeteringZoneSample\n} from \"./metering.js\";\nimport { requireInputKeys, requireInputObject, rejectUnknownFields } from \"../core/record-validation.js\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport const SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport interface SceneRadianceMeteringDerivationProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION;\n derivationId: string;\n scientificStatus: \"approximation\";\n method:\n \"renderer-provided-pre-exposure-relative-reduction\";\n spectralWeighting:\n \"not-calibrated\";\n evidence: readonly EvidenceProvenance[];\n limitation: string;\n}\n\nexport type SceneRadianceMeteringTemporalContext =\n | {\n kind: \"time-invariant\";\n }\n | {\n kind:\n \"registered-time-varying\";\n illuminationTemporalProfileId:\n string;\n timeReference:\n \"first-opening-boundary-phase\";\n captureTimeSecondsFromReference:\n number;\n };\n\nexport interface SceneRadianceMeteringSourceContext {\n kind:\n \"scene-radiance-provider-derived-relative\";\n sceneId: string;\n sceneStateId: string;\n providerProfileId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n derivationProfileId: string;\n providerScientificStatus:\n SceneRadianceProviderProfile[\"scientificStatus\"];\n materialResponseFidelity:\n ReturnType<\n typeof assessSceneMaterialResponseFidelity\n >;\n temporal:\n SceneRadianceMeteringTemporalContext;\n spectralReductionCalibrated: false;\n calibratedLuminanceClaimAuthorized:\n false;\n calibratedSceneRadianceClaimAuthorized:\n false;\n}\n\nexport interface SceneRadianceDerivedExposureMeteringSampleSet\n extends ExposureMeteringSampleSet {\n sourceContext:\n SceneRadianceMeteringSourceContext;\n}\n\nexport interface CreateSceneRadianceDerivedExposureMeteringSampleSetInput {\n measurementId: string;\n sceneStateId: string;\n providerProfile:\n SceneRadianceProviderProfile;\n illuminationProfile:\n SceneIlluminationProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n captureTimeSecondsFromReference?: number;\n captureGeometry:\n ResolvedCaptureGeometry;\n derivationProfile:\n SceneRadianceMeteringDerivationProfile;\n samples:\n readonly ExposureMeteringZoneSample[];\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 + \" 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 InvalidScientificInputError(\n path + \" must be finite.\"\n );\n }\n return value;\n}\n\n/**\n * Parses the declared approximation that turns renderer or provider scene data\n * into the single relative linear values the meter uses.\n *\n * The profile does not support any claim of calibrated luminance or of a\n * spectral-to-photometric conversion.\n */\nexport function parseSceneRadianceMeteringDerivationProfile(\n value: unknown\n): SceneRadianceMeteringDerivationProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceMeteringDerivationProfile\", [\"schemaVersion\", \"scientificStatus\", \"method\", \"spectralWeighting\", \"derivationId\", \"evidence\", \"limitation\"]\n );\n\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.method !==\n \"renderer-provided-pre-exposure-relative-reduction\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.method must be \"renderer-provided-pre-exposure-relative-reduction\".'\n );\n }\n if (\n record.spectralWeighting !==\n \"not-calibrated\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.spectralWeighting must be \"not-calibrated\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION,\n derivationId:\n requireNonEmptyString(\n record.derivationId,\n \"sceneRadianceMeteringDerivationProfile.derivationId\"\n ),\n scientificStatus: \"approximation\",\n method:\n \"renderer-provided-pre-exposure-relative-reduction\",\n spectralWeighting:\n \"not-calibrated\",\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceMeteringDerivationProfile.evidence\"\n ),\n limitation:\n requireNonEmptyString(\n record.limitation,\n \"sceneRadianceMeteringDerivationProfile.limitation\"\n )\n };\n}\n\nfunction validateProviderContext(\n input:\n CreateSceneRadianceDerivedExposureMeteringSampleSetInput\n): ReturnType<\n typeof assessSceneMaterialResponseFidelity\n> {\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile\n } = input;\n requireInputObject(providerProfile, \"providerProfile\");\n requireInputObject(providerProfile.fidelity, \"providerProfile.fidelity\");\n requireInputObject(illuminationProfile, \"illuminationProfile\");\n requireInputObject(materialResponseProfile, \"materialResponseProfile\");\n if (illuminationTemporalProfile !== undefined) requireInputObject(illuminationTemporalProfile, \"illuminationTemporalProfile\");\n\n if (\n providerProfile.sceneId !==\n illuminationProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile.sceneId !==\n materialResponseProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile.illuminationProfileId !==\n illuminationProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n }\n if (\n providerProfile.materialResponseProfileId !==\n materialResponseProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n if (\n providerProfile.fidelity.material !==\n materialResponseFidelity\n ) {\n throw new InvalidScientificInputError(\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n }\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n if (\n input\n .captureTimeSecondsFromReference !==\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"captureTimeSecondsFromReference must be omitted for a time-invariant provider context.\"\n );\n }\n return materialResponseFidelity;\n }\n\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n if (\n providerProfile\n .illuminationTemporalProfileId !==\n illuminationTemporalProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n }\n if (\n providerProfile.sceneId !==\n illuminationTemporalProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile\n .illuminationProfileId !==\n illuminationTemporalProfile\n .illuminationProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n if (!Array.isArray(illuminationProfile.sources) || !Array.isArray(illuminationTemporalProfile.sourceBindings)) {\n throw new InvalidConfigurationError(\"illuminationProfile.sources and illuminationTemporalProfile.sourceBindings must be arrays.\");\n }\n illuminationProfile.sources.forEach((entry, index) => requireInputObject(entry, \"illuminationProfile.sources[\" + index + \"]\"));\n illuminationTemporalProfile.sourceBindings.forEach((entry, index) => requireInputObject(entry, \"illuminationTemporalProfile.sourceBindings[\" + index + \"]\"));\n const knownSourceIds =\n new Set(\n illuminationProfile.sources.map(\n (entry) => entry.sourceId\n )\n );\n for (\n const binding of\n illuminationTemporalProfile\n .sourceBindings\n ) {\n if (\n !knownSourceIds.has(\n binding.sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Temporal illumination source binding references a sourceId that is not declared by the illumination profile.\"\n );\n }\n }\n if (\n input\n .captureTimeSecondsFromReference ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"Time-varying scene-radiance metering requires an explicit captureTimeSecondsFromReference.\"\n );\n }\n requireFinite(\n input.captureTimeSecondsFromReference,\n \"captureTimeSecondsFromReference\"\n );\n\n return materialResponseFidelity;\n}\n\n/**\n * Builds a set of relative pre-exposure meter samples tied to one validated\n * scene-radiance provider context.\n *\n * The caller or renderer still supplies the relative sample values. This\n * bridge only checks identity and timing. It does not convert spectral\n * radiance into luminance, and it does not define a calibrated meter spectral\n * response.\n */\nexport function createSceneRadianceDerivedExposureMeteringSampleSet(\n input:\n CreateSceneRadianceDerivedExposureMeteringSampleSetInput\n): SceneRadianceDerivedExposureMeteringSampleSet {\n requireInputKeys(input, \"createSceneRadianceDerivedExposureMeteringSampleSet\", [\"measurementId\", \"sceneStateId\", \"providerProfile\", \"illuminationProfile\", \"materialResponseProfile\", \"illuminationTemporalProfile\", \"captureTimeSecondsFromReference\", \"captureGeometry\", \"derivationProfile\", \"samples\"]);\n const derivationProfile =\n parseSceneRadianceMeteringDerivationProfile(\n input.derivationProfile\n );\n const materialResponseFidelity =\n validateProviderContext(input);\n\n if (\n typeof input.measurementId !==\n \"string\" ||\n input.measurementId.trim().length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"measurementId must be a non-empty string.\"\n );\n }\n if (\n typeof input.sceneStateId !==\n \"string\" ||\n input.sceneStateId.trim().length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"sceneStateId must be a non-empty string.\"\n );\n }\n if (\n !Array.isArray(input.samples) ||\n input.samples.length === 0\n ) {\n throw new InvalidConfigurationError(\n \"samples must be a non-empty array.\"\n );\n }\n\n const temporal:\n SceneRadianceMeteringTemporalContext =\n input.providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ? {\n kind: \"time-invariant\"\n }\n : {\n kind:\n \"registered-time-varying\",\n illuminationTemporalProfileId:\n input.providerProfile\n .illuminationTemporalProfileId,\n timeReference:\n \"first-opening-boundary-phase\",\n captureTimeSecondsFromReference:\n input\n .captureTimeSecondsFromReference!\n };\n\n return {\n measurementId:\n input.measurementId.trim(),\n sceneStateId:\n input.sceneStateId.trim(),\n inputDomain:\n \"relative-pre-exposure-linear-signal\",\n captureRegion:\n \"oriented-active-capture\",\n captureGeometry:\n input.captureGeometry,\n processingState: {\n exposureSettingsApplied: false,\n whiteBalanceApplied: false,\n toneMappingApplied: false,\n displayGammaApplied: false,\n sharpeningApplied: false\n },\n samples: input.samples,\n sourceContext: {\n kind:\n \"scene-radiance-provider-derived-relative\",\n sceneId:\n input.providerProfile.sceneId,\n sceneStateId:\n input.sceneStateId.trim(),\n providerProfileId:\n input.providerProfile.profileId,\n illuminationProfileId:\n input.illuminationProfile.profileId,\n materialResponseProfileId:\n input.materialResponseProfile\n .profileId,\n derivationProfileId:\n derivationProfile.derivationId,\n providerScientificStatus:\n input.providerProfile\n .scientificStatus,\n materialResponseFidelity,\n temporal,\n spectralReductionCalibrated:\n false,\n calibratedLuminanceClaimAuthorized:\n false,\n calibratedSceneRadianceClaimAuthorized:\n false\n }\n };\n}\n"]}
1
+ {"version":3,"file":"metering-scene-radiance.js","sourceRoot":"","sources":["../../src/exposure/metering-scene-radiance.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Links scene radiance to metering.\n *\n * The profile parser reads the declared approximation that turns renderer or provider scene data into\n * the single relative linear values the meter uses. The profile does not support any claim of\n * calibrated luminance or of a spectral-to-photometric conversion.\n *\n * The sample-set function builds a set of relative pre-exposure meter samples tied to one validated\n * scene-radiance provider context. The caller or renderer still supplies the relative sample values.\n * This bridge only checks identity and timing. It does not convert spectral radiance into luminance,\n * and it does not define a calibrated meter spectral response.\n * @see docs/USAGE.md for the equations, units, coordinate conventions, known blockers and support\n * limits.\n */\n\nimport { InvalidConfigurationError } from \"../core/configuration-error.js\";\nimport {\n parseEvidenceList,\n type EvidenceProvenance\n} from \"../core/evidence-provenance.js\";\nimport { InvalidScientificInputError } from \"../core/validation.js\";\nimport type {\n ResolvedCaptureGeometry\n} from \"../output/capture-geometry.js\";\nimport {\n assessSceneMaterialResponseFidelity,\n type SceneMaterialResponseProfile,\n type SceneRadianceProviderProfile\n} from \"../schema/scene-radiance.js\";\nimport type {\n SceneIlluminationProfile\n} from \"../schema/illumination.js\";\nimport type {\n SceneIlluminationTemporalProfile\n} from \"../schema/illumination-temporal.js\";\nimport type {\n ExposureMeteringSampleSet,\n ExposureMeteringZoneSample\n} from \"./metering.js\";\nimport { requireInputKeys, requireInputObject, requireConfigRecord as requireRecord, requireTrimmedConfigString as requireNonEmptyString, requireInputFinite as requireFinite } from \"../core/record-validation.js\";\n\n\nexport const SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION =\n \"0.1.0\" as const;\n\nexport interface SceneRadianceMeteringDerivationProfile {\n schemaVersion:\n typeof SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION;\n derivationId: string;\n scientificStatus: \"approximation\";\n method:\n \"renderer-provided-pre-exposure-relative-reduction\";\n spectralWeighting:\n \"not-calibrated\";\n evidence: readonly EvidenceProvenance[];\n limitation: string;\n}\n\nexport type SceneRadianceMeteringTemporalContext =\n | {\n kind: \"time-invariant\";\n }\n | {\n kind:\n \"registered-time-varying\";\n illuminationTemporalProfileId:\n string;\n timeReference:\n \"first-opening-boundary-phase\";\n captureTimeSecondsFromReference:\n number;\n };\n\nexport interface SceneRadianceMeteringSourceContext {\n kind:\n \"scene-radiance-provider-derived-relative\";\n sceneId: string;\n sceneStateId: string;\n providerProfileId: string;\n illuminationProfileId: string;\n materialResponseProfileId: string;\n derivationProfileId: string;\n providerScientificStatus:\n SceneRadianceProviderProfile[\"scientificStatus\"];\n materialResponseFidelity:\n ReturnType<\n typeof assessSceneMaterialResponseFidelity\n >;\n temporal:\n SceneRadianceMeteringTemporalContext;\n spectralReductionCalibrated: false;\n calibratedLuminanceClaimAuthorized:\n false;\n calibratedSceneRadianceClaimAuthorized:\n false;\n}\n\nexport interface SceneRadianceDerivedExposureMeteringSampleSet\n extends ExposureMeteringSampleSet {\n sourceContext:\n SceneRadianceMeteringSourceContext;\n}\n\nexport interface CreateSceneRadianceDerivedExposureMeteringSampleSetInput {\n measurementId: string;\n sceneStateId: string;\n providerProfile:\n SceneRadianceProviderProfile;\n illuminationProfile:\n SceneIlluminationProfile;\n materialResponseProfile:\n SceneMaterialResponseProfile;\n illuminationTemporalProfile?:\n SceneIlluminationTemporalProfile;\n captureTimeSecondsFromReference?: number;\n captureGeometry:\n ResolvedCaptureGeometry;\n derivationProfile:\n SceneRadianceMeteringDerivationProfile;\n samples:\n readonly ExposureMeteringZoneSample[];\n}\n\n/**\n * Parses the declared approximation that turns renderer or provider scene data\n * into the single relative linear values the meter uses.\n *\n * The profile does not support any claim of calibrated luminance or of a\n * spectral-to-photometric conversion.\n */\nexport function parseSceneRadianceMeteringDerivationProfile(\n value: unknown\n): SceneRadianceMeteringDerivationProfile {\n const record = requireRecord(\n value,\n \"sceneRadianceMeteringDerivationProfile\", [\"schemaVersion\", \"scientificStatus\", \"method\", \"spectralWeighting\", \"derivationId\", \"evidence\", \"limitation\"]\n );\n\n if (\n record.schemaVersion !==\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.schemaVersion must be \"' +\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION +\n '\".'\n );\n }\n if (\n record.scientificStatus !==\n \"approximation\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.scientificStatus must be \"approximation\" in schema 0.1.0.'\n );\n }\n if (\n record.method !==\n \"renderer-provided-pre-exposure-relative-reduction\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.method must be \"renderer-provided-pre-exposure-relative-reduction\".'\n );\n }\n if (\n record.spectralWeighting !==\n \"not-calibrated\"\n ) {\n throw new InvalidConfigurationError(\n 'sceneRadianceMeteringDerivationProfile.spectralWeighting must be \"not-calibrated\" in schema 0.1.0.'\n );\n }\n\n return {\n schemaVersion:\n SCENE_RADIANCE_METERING_DERIVATION_SCHEMA_VERSION,\n derivationId:\n requireNonEmptyString(\n record.derivationId,\n \"sceneRadianceMeteringDerivationProfile.derivationId\"\n ),\n scientificStatus: \"approximation\",\n method:\n \"renderer-provided-pre-exposure-relative-reduction\",\n spectralWeighting:\n \"not-calibrated\",\n evidence: parseEvidenceList(\n record.evidence,\n \"sceneRadianceMeteringDerivationProfile.evidence\"\n ),\n limitation:\n requireNonEmptyString(\n record.limitation,\n \"sceneRadianceMeteringDerivationProfile.limitation\"\n )\n };\n}\n\nfunction validateProviderContext(\n input:\n CreateSceneRadianceDerivedExposureMeteringSampleSetInput\n): ReturnType<\n typeof assessSceneMaterialResponseFidelity\n> {\n const {\n providerProfile,\n illuminationProfile,\n illuminationTemporalProfile,\n materialResponseProfile\n } = input;\n requireInputObject(providerProfile, \"providerProfile\");\n requireInputObject(providerProfile.fidelity, \"providerProfile.fidelity\");\n requireInputObject(illuminationProfile, \"illuminationProfile\");\n requireInputObject(materialResponseProfile, \"materialResponseProfile\");\n if (illuminationTemporalProfile !== undefined) requireInputObject(illuminationTemporalProfile, \"illuminationTemporalProfile\");\n\n if (\n providerProfile.sceneId !==\n illuminationProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and illumination profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile.sceneId !==\n materialResponseProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and material-response profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile.illuminationProfileId !==\n illuminationProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationProfileId must match the supplied illumination profile.\"\n );\n }\n if (\n providerProfile.materialResponseProfileId !==\n materialResponseProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider materialResponseProfileId must match the supplied material-response profile.\"\n );\n }\n\n const materialResponseFidelity =\n assessSceneMaterialResponseFidelity(\n materialResponseProfile\n );\n if (\n providerProfile.fidelity.material !==\n materialResponseFidelity\n ) {\n throw new InvalidScientificInputError(\n \"Provider material fidelity must match the supplied material-response profile.\"\n );\n }\n\n if (\n providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ) {\n if (\n illuminationTemporalProfile !==\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"A temporal illumination profile was supplied but the provider profile does not bind one.\"\n );\n }\n if (\n input\n .captureTimeSecondsFromReference !==\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"captureTimeSecondsFromReference must be omitted for a time-invariant provider context.\"\n );\n }\n return materialResponseFidelity;\n }\n\n if (\n illuminationTemporalProfile ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationTemporalProfileId requires the matching temporal illumination profile.\"\n );\n }\n if (\n providerProfile\n .illuminationTemporalProfileId !==\n illuminationTemporalProfile.profileId\n ) {\n throw new InvalidScientificInputError(\n \"Provider illuminationTemporalProfileId must match the supplied temporal illumination profile.\"\n );\n }\n if (\n providerProfile.sceneId !==\n illuminationTemporalProfile.sceneId\n ) {\n throw new InvalidScientificInputError(\n \"Provider and temporal illumination profiles must reference the same sceneId.\"\n );\n }\n if (\n providerProfile\n .illuminationProfileId !==\n illuminationTemporalProfile\n .illuminationProfileId\n ) {\n throw new InvalidScientificInputError(\n \"Temporal illumination profile must bind the provider's illuminationProfileId.\"\n );\n }\n\n if (!Array.isArray(illuminationProfile.sources) || !Array.isArray(illuminationTemporalProfile.sourceBindings)) {\n throw new InvalidConfigurationError(\"illuminationProfile.sources and illuminationTemporalProfile.sourceBindings must be arrays.\");\n }\n illuminationProfile.sources.forEach((entry, index) => requireInputObject(entry, \"illuminationProfile.sources[\" + index + \"]\"));\n illuminationTemporalProfile.sourceBindings.forEach((entry, index) => requireInputObject(entry, \"illuminationTemporalProfile.sourceBindings[\" + index + \"]\"));\n const knownSourceIds =\n new Set(\n illuminationProfile.sources.map(\n (entry) => entry.sourceId\n )\n );\n for (\n const binding of\n illuminationTemporalProfile\n .sourceBindings\n ) {\n if (\n !knownSourceIds.has(\n binding.sourceId\n )\n ) {\n throw new InvalidScientificInputError(\n \"Temporal illumination source binding references a sourceId that is not declared by the illumination profile.\"\n );\n }\n }\n if (\n input\n .captureTimeSecondsFromReference ===\n undefined\n ) {\n throw new InvalidScientificInputError(\n \"Time-varying scene-radiance metering requires an explicit captureTimeSecondsFromReference.\"\n );\n }\n requireFinite(\n input.captureTimeSecondsFromReference,\n \"captureTimeSecondsFromReference\"\n );\n\n return materialResponseFidelity;\n}\n\n/**\n * Builds a set of relative pre-exposure meter samples tied to one validated\n * scene-radiance provider context.\n *\n * The caller or renderer still supplies the relative sample values. This\n * bridge only checks identity and timing. It does not convert spectral\n * radiance into luminance, and it does not define a calibrated meter spectral\n * response.\n */\nexport function createSceneRadianceDerivedExposureMeteringSampleSet(\n input:\n CreateSceneRadianceDerivedExposureMeteringSampleSetInput\n): SceneRadianceDerivedExposureMeteringSampleSet {\n requireInputKeys(input, \"createSceneRadianceDerivedExposureMeteringSampleSet\", [\"measurementId\", \"sceneStateId\", \"providerProfile\", \"illuminationProfile\", \"materialResponseProfile\", \"illuminationTemporalProfile\", \"captureTimeSecondsFromReference\", \"captureGeometry\", \"derivationProfile\", \"samples\"]);\n const derivationProfile =\n parseSceneRadianceMeteringDerivationProfile(\n input.derivationProfile\n );\n const materialResponseFidelity =\n validateProviderContext(input);\n\n if (\n typeof input.measurementId !==\n \"string\" ||\n input.measurementId.trim().length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"measurementId must be a non-empty string.\"\n );\n }\n if (\n typeof input.sceneStateId !==\n \"string\" ||\n input.sceneStateId.trim().length ===\n 0\n ) {\n throw new InvalidConfigurationError(\n \"sceneStateId must be a non-empty string.\"\n );\n }\n if (\n !Array.isArray(input.samples) ||\n input.samples.length === 0\n ) {\n throw new InvalidConfigurationError(\n \"samples must be a non-empty array.\"\n );\n }\n\n const temporal:\n SceneRadianceMeteringTemporalContext =\n input.providerProfile\n .illuminationTemporalProfileId ===\n undefined\n ? {\n kind: \"time-invariant\"\n }\n : {\n kind:\n \"registered-time-varying\",\n illuminationTemporalProfileId:\n input.providerProfile\n .illuminationTemporalProfileId,\n timeReference:\n \"first-opening-boundary-phase\",\n captureTimeSecondsFromReference:\n input\n .captureTimeSecondsFromReference!\n };\n\n return {\n measurementId:\n input.measurementId.trim(),\n sceneStateId:\n input.sceneStateId.trim(),\n inputDomain:\n \"relative-pre-exposure-linear-signal\",\n captureRegion:\n \"oriented-active-capture\",\n captureGeometry:\n input.captureGeometry,\n processingState: {\n exposureSettingsApplied: false,\n whiteBalanceApplied: false,\n toneMappingApplied: false,\n displayGammaApplied: false,\n sharpeningApplied: false\n },\n samples: input.samples,\n sourceContext: {\n kind:\n \"scene-radiance-provider-derived-relative\",\n sceneId:\n input.providerProfile.sceneId,\n sceneStateId:\n input.sceneStateId.trim(),\n providerProfileId:\n input.providerProfile.profileId,\n illuminationProfileId:\n input.illuminationProfile.profileId,\n materialResponseProfileId:\n input.materialResponseProfile\n .profileId,\n derivationProfileId:\n derivationProfile.derivationId,\n providerScientificStatus:\n input.providerProfile\n .scientificStatus,\n materialResponseFidelity,\n temporal,\n spectralReductionCalibrated:\n false,\n calibratedLuminanceClaimAuthorized:\n false,\n calibratedSceneRadianceClaimAuthorized:\n false\n }\n };\n}\n"]}
@@ -12,38 +12,9 @@
12
12
  * limits.
13
13
  */
14
14
  import { InvalidScientificInputError } from "../core/validation.js";
15
- import { requireInputObject, requireInputKeys } from "../core/record-validation.js";
15
+ import { requireInputObject, requireInputKeys, requireTrimmedConfigString as requireNonEmptyString, requireInputFinite as requireFinite, requireInputFiniteAboveZero as requirePositiveFinite, requireInputFiniteAtLeastZero as requireNonNegativeFinite } from "../core/record-validation.js";
16
16
  import { InvalidConfigurationError } from "../core/configuration-error.js";
17
17
  export const EXPOSURE_METER_TARGET_SCHEMA_VERSION = "0.1.0";
18
- function requireNonEmptyString(value, path) {
19
- if (typeof value !== "string" ||
20
- value.trim().length === 0) {
21
- throw new InvalidConfigurationError(path + " must be a non-empty string.");
22
- }
23
- return value.trim();
24
- }
25
- function requireFinite(value, path) {
26
- if (typeof value !== "number" ||
27
- !Number.isFinite(value)) {
28
- throw new InvalidScientificInputError(path + " must be finite.");
29
- }
30
- return value;
31
- }
32
- function requirePositiveFinite(value, path) {
33
- const parsed = requireFinite(value, path);
34
- if (parsed <= 0) {
35
- throw new InvalidScientificInputError(path + " must be greater than zero.");
36
- }
37
- return parsed;
38
- }
39
- function requireNonNegativeFinite(value, path) {
40
- const parsed = requireFinite(value, path);
41
- if (parsed < 0) {
42
- throw new InvalidScientificInputError(path +
43
- " must be greater than or equal to zero.");
44
- }
45
- return parsed;
46
- }
47
18
  function meterSnapshotIdentity(result) {
48
19
  const hasSpatialId = "measurementId" in result;
49
20
  const hasTemporalId = "temporalMeasurementId" in