@bvdmitri/gyroview 0.0.0-stage → 0.9.0-cutaway.2

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 (302) hide show
  1. package/CHANGELOG.md +402 -0
  2. package/LICENSE +21 -0
  3. package/README.md +313 -2
  4. package/dist/define.d.ts +3 -0
  5. package/dist/define.js +4 -0
  6. package/dist/index.d.ts +1204 -0
  7. package/dist/index.js +12 -0
  8. package/dist/packages/adapters/blob/src/BlobRandomAccessSource.js +36 -0
  9. package/dist/packages/adapters/fetch/src/HttpByteStream.js +173 -0
  10. package/dist/packages/adapters/fetch/src/HttpRangeSource.js +37 -0
  11. package/dist/packages/adapters/fetch/src/HttpResource.js +227 -0
  12. package/dist/packages/adapters/fetch/src/HttpResourceLocator.js +35 -0
  13. package/dist/packages/adapters/fetch/src/contentRange.js +15 -0
  14. package/dist/packages/adapters/fetch/src/httpRequest.js +136 -0
  15. package/dist/packages/adapters/fetch/src/passingFailures.js +23 -0
  16. package/dist/packages/adapters/fetch/src/rangeFailures.js +16 -0
  17. package/dist/packages/adapters/fetch/src/recordingVersion.js +37 -0
  18. package/dist/packages/adapters/mediabunny/src/MediabunnyAudioPackager.js +162 -0
  19. package/dist/packages/adapters/mediabunny/src/MediabunnyCodecReader.js +93 -0
  20. package/dist/packages/adapters/mediabunny/src/SegmentChannel.js +135 -0
  21. package/dist/packages/adapters/mediabunny/src/bufferSources.js +12 -0
  22. package/dist/packages/adapters/mediabunny/src/decoderConfigurations.js +43 -0
  23. package/dist/packages/adapters/mediabunny/src/trackColour.js +20 -0
  24. package/dist/packages/adapters/mse-audio/src/MediaSourceAudioClock.js +138 -0
  25. package/dist/packages/adapters/mse-audio/src/SourceBufferFeeder.js +263 -0
  26. package/dist/packages/adapters/mse-audio/src/events.js +26 -0
  27. package/dist/packages/adapters/mse-audio/src/mediaSourceSupport.js +81 -0
  28. package/dist/packages/adapters/three/src/ThreeFrameRenderer.js +215 -0
  29. package/dist/packages/adapters/three/src/compileAndProve.js +14 -0
  30. package/dist/packages/adapters/three/src/conversionUniforms.js +60 -0
  31. package/dist/packages/adapters/three/src/drawSchedules.js +13 -0
  32. package/dist/packages/adapters/three/src/fullscreenPass.js +52 -0
  33. package/dist/packages/adapters/three/src/glslLiterals.js +10 -0
  34. package/dist/packages/adapters/three/src/lensTextures.js +34 -0
  35. package/dist/packages/adapters/three/src/matrixCorrections.js +34 -0
  36. package/dist/packages/adapters/three/src/pictureMaterials.js +44 -0
  37. package/dist/packages/adapters/three/src/renderInto.js +15 -0
  38. package/dist/packages/adapters/three/src/rendererParts.js +108 -0
  39. package/dist/packages/adapters/three/src/rendererUniforms.js +176 -0
  40. package/dist/packages/adapters/three/src/samplingStrategies.js +26 -0
  41. package/dist/packages/adapters/three/src/scissorBox.js +20 -0
  42. package/dist/packages/adapters/three/src/seamMeter/SeamMeterPass.js +85 -0
  43. package/dist/packages/adapters/three/src/seamMeter/rowMeans.js +42 -0
  44. package/dist/packages/adapters/three/src/shaderPrograms.js +68 -0
  45. package/dist/packages/adapters/three/src/shaders/analysis.frag.js +4 -0
  46. package/dist/packages/adapters/three/src/shaders/displayConversion.js +4 -0
  47. package/dist/packages/adapters/three/src/shaders/equirectangularRays.js +4 -0
  48. package/dist/packages/adapters/three/src/shaders/fixedJoin.js +4 -0
  49. package/dist/packages/adapters/three/src/shaders/fullscreen.vert.js +4 -0
  50. package/dist/packages/adapters/three/src/shaders/header.js +4 -0
  51. package/dist/packages/adapters/three/src/shaders/lensModels.js +4 -0
  52. package/dist/packages/adapters/three/src/shaders/lensSampling.js +4 -0
  53. package/dist/packages/adapters/three/src/shaders/lensTextures.js +4 -0
  54. package/dist/packages/adapters/three/src/shaders/rawLenses.frag.js +4 -0
  55. package/dist/packages/adapters/three/src/shaders/rectilinearRays.js +4 -0
  56. package/dist/packages/adapters/three/src/shaders/screenAreas.js +4 -0
  57. package/dist/packages/adapters/three/src/shaders/stitch.frag.js +4 -0
  58. package/dist/packages/adapters/three/src/threeMatrix.js +10 -0
  59. package/dist/packages/adapters/three/src/webglRenderer.js +37 -0
  60. package/dist/packages/adapters/webcodecs/src/WebCodecsVideoDecoderPort.js +152 -0
  61. package/dist/packages/adapters/webcodecs/src/colorSpaceOf.js +32 -0
  62. package/dist/packages/core/src/application/download/BlockStore.js +97 -0
  63. package/dist/packages/core/src/application/download/DownloadedAudioSamples.js +50 -0
  64. package/dist/packages/core/src/application/download/DownloadedVideoTrack.js +122 -0
  65. package/dist/packages/core/src/application/download/FileDownload.js +208 -0
  66. package/dist/packages/core/src/application/download/RecordingBuffer.js +22 -0
  67. package/dist/packages/core/src/application/download/SampleCursor.js +89 -0
  68. package/dist/packages/core/src/application/download/SourceByteStream.js +46 -0
  69. package/dist/packages/core/src/application/download/Transfers.js +82 -0
  70. package/dist/packages/core/src/application/download/startFileDownload.js +37 -0
  71. package/dist/packages/core/src/application/gainMatching/GainMatching.js +76 -0
  72. package/dist/packages/core/src/application/gainMatching/GainMatchingFrameSink.js +80 -0
  73. package/dist/packages/core/src/application/gainMatching/referenceLensOf.js +18 -0
  74. package/dist/packages/core/src/application/playback/Buffering.js +54 -0
  75. package/dist/packages/core/src/application/playback/ClockStart.js +55 -0
  76. package/dist/packages/core/src/application/playback/ClockWatch.js +76 -0
  77. package/dist/packages/core/src/application/playback/DecodePipeline.js +234 -0
  78. package/dist/packages/core/src/application/playback/DecodeRun.js +108 -0
  79. package/dist/packages/core/src/application/playback/FramePairQueue.js +93 -0
  80. package/dist/packages/core/src/application/playback/FramePairer.js +77 -0
  81. package/dist/packages/core/src/application/playback/PictureOnScreen.js +56 -0
  82. package/dist/packages/core/src/application/playback/PlaybackSession.js +410 -0
  83. package/dist/packages/core/src/application/playback/SeekOrder.js +35 -0
  84. package/dist/packages/core/src/application/playback/SessionLifecycle.js +42 -0
  85. package/dist/packages/core/src/application/playback/StartGate.js +69 -0
  86. package/dist/packages/core/src/application/playback/TimeUpdates.js +31 -0
  87. package/dist/packages/core/src/application/playback/WallClock.js +46 -0
  88. package/dist/packages/core/src/application/playback/keyframeTimeAt.js +15 -0
  89. package/dist/packages/core/src/application/playback/probeDecoding.js +182 -0
  90. package/dist/packages/core/src/application/recording/frameTimesOf.js +21 -0
  91. package/dist/packages/core/src/application/recording/inspectLayout.js +21 -0
  92. package/dist/packages/core/src/application/recording/inspectRecording.js +125 -0
  93. package/dist/packages/core/src/application/recording/locateOtherLensFile.js +18 -0
  94. package/dist/packages/core/src/application/recording/motionOf.js +43 -0
  95. package/dist/packages/core/src/application/recording/readRecording.js +31 -0
  96. package/dist/packages/core/src/application/recording/readRecordingFiles.js +130 -0
  97. package/dist/packages/core/src/application/recording/readSampleTable.js +27 -0
  98. package/dist/packages/core/src/application/recording/timeRecording.js +57 -0
  99. package/dist/packages/core/src/application/stabilization/StabilizingFrameSink.js +33 -0
  100. package/dist/packages/core/src/domain/colour/DisplayConversion.js +137 -0
  101. package/dist/packages/core/src/domain/colour/TrackColour.js +38 -0
  102. package/dist/packages/core/src/domain/colour/gainMatch.js +64 -0
  103. package/dist/packages/core/src/domain/colour/matrixCorrection.js +76 -0
  104. package/dist/packages/core/src/domain/container/KeyframeRule.js +7 -0
  105. package/dist/packages/core/src/domain/container/SampleTable.js +29 -0
  106. package/dist/packages/core/src/domain/container/TrackSampleTable.js +96 -0
  107. package/dist/packages/core/src/domain/container/presentationOrder.js +10 -0
  108. package/dist/packages/core/src/domain/download/DownloadPolicy.js +84 -0
  109. package/dist/packages/core/src/domain/download/isReadyToResume.js +27 -0
  110. package/dist/packages/core/src/domain/download/planDownloads.js +175 -0
  111. package/dist/packages/core/src/domain/download/trackNeeds.js +32 -0
  112. package/dist/packages/core/src/domain/format/boxes/BoxLayout.js +7 -0
  113. package/dist/packages/core/src/domain/format/boxes/boxConstants.js +16 -0
  114. package/dist/packages/core/src/domain/format/boxes/boxHeader.js +44 -0
  115. package/dist/packages/core/src/domain/format/boxes/scanBoxes.js +32 -0
  116. package/dist/packages/core/src/domain/format/calibration/CalibrationVersion.js +16 -0
  117. package/dist/packages/core/src/domain/format/calibration/layouts/CalibrationStringLayout.js +34 -0
  118. package/dist/packages/core/src/domain/format/calibration/layouts/LegacyCalibrationLayout.js +46 -0
  119. package/dist/packages/core/src/domain/format/calibration/layouts/MeiCalibrationLayout.js +121 -0
  120. package/dist/packages/core/src/domain/format/calibration/layouts/PolynomialCalibrationLayout.js +46 -0
  121. package/dist/packages/core/src/domain/format/calibration/offsetTokens.js +94 -0
  122. package/dist/packages/core/src/domain/format/calibration/parseOffsetString.js +77 -0
  123. package/dist/packages/core/src/domain/format/calibration/selectCalibration.js +59 -0
  124. package/dist/packages/core/src/domain/format/calibration/v6TermReading.js +20 -0
  125. package/dist/packages/core/src/domain/format/captureOrigin.js +34 -0
  126. package/dist/packages/core/src/domain/format/constants.js +35 -0
  127. package/dist/packages/core/src/domain/format/info/calibrationSources.js +27 -0
  128. package/dist/packages/core/src/domain/format/info/infoFields.js +116 -0
  129. package/dist/packages/core/src/domain/format/info/parseInfoRecord.js +107 -0
  130. package/dist/packages/core/src/domain/format/info/readInfoRecord.js +14 -0
  131. package/dist/packages/core/src/domain/format/layout/detectLensLayout.js +133 -0
  132. package/dist/packages/core/src/domain/format/mp4/hevcCodecString.js +161 -0
  133. package/dist/packages/core/src/domain/format/mp4/keyframeRules.js +81 -0
  134. package/dist/packages/core/src/domain/format/mp4/movieBoxes.js +52 -0
  135. package/dist/packages/core/src/domain/format/mp4/mp4BoxTypes.js +46 -0
  136. package/dist/packages/core/src/domain/format/mp4/mp4Layouts.js +183 -0
  137. package/dist/packages/core/src/domain/format/mp4/parseMovie.js +72 -0
  138. package/dist/packages/core/src/domain/format/mp4/readTable.js +31 -0
  139. package/dist/packages/core/src/domain/format/mp4/sampleLocations.js +76 -0
  140. package/dist/packages/core/src/domain/format/mp4/sampleTiming.js +120 -0
  141. package/dist/packages/core/src/domain/format/mp4/trackHeaders.js +88 -0
  142. package/dist/packages/core/src/domain/format/naming/RecordingFileName.js +70 -0
  143. package/dist/packages/core/src/domain/format/records/TrailerRecords.js +100 -0
  144. package/dist/packages/core/src/domain/format/records/exposure/parseExposureRecord.js +48 -0
  145. package/dist/packages/core/src/domain/format/records/gyro/FloatGyroSampleLayout.js +38 -0
  146. package/dist/packages/core/src/domain/format/records/gyro/RawGyroSampleLayout.js +55 -0
  147. package/dist/packages/core/src/domain/format/records/gyro/SampleColumns.js +89 -0
  148. package/dist/packages/core/src/domain/format/records/gyro/gyroLayouts.js +12 -0
  149. package/dist/packages/core/src/domain/format/records/gyro/parseGyroRecord.js +138 -0
  150. package/dist/packages/core/src/domain/format/records/trim/parseTrimRecord.js +24 -0
  151. package/dist/packages/core/src/domain/format/trailer/RecordHeader.js +23 -0
  152. package/dist/packages/core/src/domain/format/trailer/Trailer.js +23 -0
  153. package/dist/packages/core/src/domain/format/trailer/TrailerFooter.js +27 -0
  154. package/dist/packages/core/src/domain/format/trailer/locateRecords.js +80 -0
  155. package/dist/packages/core/src/domain/format/trailer/parseRecordIndex.js +28 -0
  156. package/dist/packages/core/src/domain/format/trailer/readTrailer.js +60 -0
  157. package/dist/packages/core/src/domain/motion/exposure/ExposureRecord.js +48 -0
  158. package/dist/packages/core/src/domain/motion/gyro/GyroTrack.js +70 -0
  159. package/dist/packages/core/src/domain/motion/gyro/medianStep.js +11 -0
  160. package/dist/packages/core/src/domain/motion/gyro/repairedTimeline.js +101 -0
  161. package/dist/packages/core/src/domain/motion/imu/ImuFrame.js +178 -0
  162. package/dist/packages/core/src/domain/motion/mounting/Mounting.js +131 -0
  163. package/dist/packages/core/src/domain/motion/orientation/OrientationTrack.js +142 -0
  164. package/dist/packages/core/src/domain/motion/orientation/estimateGyroBias.js +72 -0
  165. package/dist/packages/core/src/domain/motion/orientation/gravity.js +97 -0
  166. package/dist/packages/core/src/domain/motion/stabilization/Stabilizer.js +13 -0
  167. package/dist/packages/core/src/domain/motion/stabilization/stabilizers.js +86 -0
  168. package/dist/packages/core/src/domain/motion/timing/CaptureClock.js +41 -0
  169. package/dist/packages/core/src/domain/motion/timing/FrameTimes.js +85 -0
  170. package/dist/packages/core/src/domain/motion/timing/frameTimeSources.js +58 -0
  171. package/dist/packages/core/src/domain/motion/timing/resolveFrameTimes.js +68 -0
  172. package/dist/packages/core/src/domain/optics/EquidistantModel.js +34 -0
  173. package/dist/packages/core/src/domain/optics/MeiDistortion.js +27 -0
  174. package/dist/packages/core/src/domain/optics/MeiModel.js +27 -0
  175. package/dist/packages/core/src/domain/optics/PolynomialModel.js +39 -0
  176. package/dist/packages/core/src/domain/optics/lensPose.js +49 -0
  177. package/dist/packages/core/src/domain/optics/opticsConstants.js +5 -0
  178. package/dist/packages/core/src/domain/optics/scaledProjection.js +30 -0
  179. package/dist/packages/core/src/domain/playback/PlayerState.js +83 -0
  180. package/dist/packages/core/src/domain/rendition/RenditionSpan.js +70 -0
  181. package/dist/packages/core/src/domain/stitching/LensLayout.js +21 -0
  182. package/dist/packages/core/src/domain/stitching/StitchingSetup.js +87 -0
  183. package/dist/packages/core/src/domain/stitching/seamRing.js +4 -0
  184. package/dist/packages/core/src/domain/view/Framing.js +37 -0
  185. package/dist/packages/core/src/domain/view/Picture.js +12 -0
  186. package/dist/packages/core/src/domain/view/PictureQuality.js +26 -0
  187. package/dist/packages/core/src/domain/view/ViewMode.js +9 -0
  188. package/dist/packages/core/src/domain/view/ViewState.js +54 -0
  189. package/dist/packages/core/src/domain/view/lensTilesView.js +64 -0
  190. package/dist/packages/core/src/domain/view/magnification.js +103 -0
  191. package/dist/packages/core/src/domain/view/motionLookView.js +100 -0
  192. package/dist/packages/core/src/domain/view/normalView.js +37 -0
  193. package/dist/packages/core/src/domain/view/panoramaView.js +95 -0
  194. package/dist/packages/core/src/domain/view/rectilinear.js +53 -0
  195. package/dist/packages/core/src/domain/view/screenLayout.js +129 -0
  196. package/dist/packages/core/src/domain/view/screenLook.js +74 -0
  197. package/dist/packages/core/src/domain/view/viewGestures.js +104 -0
  198. package/dist/packages/core/src/domain/view/viewModes.js +31 -0
  199. package/dist/packages/core/src/ports/FramePair.js +6 -0
  200. package/dist/packages/core/src/shared/async/Deferred.js +42 -0
  201. package/dist/packages/core/src/shared/async/RunStop.js +40 -0
  202. package/dist/packages/core/src/shared/async/iteration.js +24 -0
  203. package/dist/packages/core/src/shared/binary/ByteRange.js +50 -0
  204. package/dist/packages/core/src/shared/binary/ByteRangeSet.js +85 -0
  205. package/dist/packages/core/src/shared/binary/ByteReader.js +104 -0
  206. package/dist/packages/core/src/shared/binary/concatenated.js +15 -0
  207. package/dist/packages/core/src/shared/errors/GyroViewError.js +140 -0
  208. package/dist/packages/core/src/shared/errors/reportLater.js +11 -0
  209. package/dist/packages/core/src/shared/events/Outbox.js +68 -0
  210. package/dist/packages/core/src/shared/events/TypedEmitter.js +55 -0
  211. package/dist/packages/core/src/shared/keysOf.js +10 -0
  212. package/dist/packages/core/src/shared/lazy.js +11 -0
  213. package/dist/packages/core/src/shared/mapRecord.js +11 -0
  214. package/dist/packages/core/src/shared/math/Matrix3.js +121 -0
  215. package/dist/packages/core/src/shared/math/Quaternion.js +133 -0
  216. package/dist/packages/core/src/shared/math/Vector3.js +58 -0
  217. package/dist/packages/core/src/shared/math/clamp.js +9 -0
  218. package/dist/packages/core/src/shared/math/countAtOrBelow.js +31 -0
  219. package/dist/packages/core/src/shared/math/minimum.js +17 -0
  220. package/dist/packages/core/src/shared/protobuf/ProtobufMessage.js +143 -0
  221. package/dist/packages/core/src/shared/protobuf/wireFormat.js +16 -0
  222. package/dist/packages/core/src/shared/text/urlPath.js +31 -0
  223. package/dist/packages/core/src/shared/text/utf8.js +12 -0
  224. package/dist/packages/core/src/shared/units/angle.js +22 -0
  225. package/dist/packages/core/src/shared/units/time.js +13 -0
  226. package/dist/packages/player/src/PlayerSource.js +14 -0
  227. package/dist/packages/player/src/browserPlayer.js +20 -0
  228. package/dist/packages/player/src/choices.js +24 -0
  229. package/dist/packages/player/src/composition/AnimationFrameDraws.js +38 -0
  230. package/dist/packages/player/src/composition/BrowserAttitudeSensor.js +191 -0
  231. package/dist/packages/player/src/composition/Disposables.js +31 -0
  232. package/dist/packages/player/src/composition/DrawingBufferFit.js +119 -0
  233. package/dist/packages/player/src/composition/animationFrames.js +9 -0
  234. package/dist/packages/player/src/composition/attitudeSensor.js +18 -0
  235. package/dist/packages/player/src/composition/browserPorts.js +80 -0
  236. package/dist/packages/player/src/composition/buildPipeline.js +186 -0
  237. package/dist/packages/player/src/composition/ensureDecodable.js +62 -0
  238. package/dist/packages/player/src/composition/openInputs.js +120 -0
  239. package/dist/packages/player/src/composition/openRecording.js +41 -0
  240. package/dist/packages/player/src/composition/readInputs.js +25 -0
  241. package/dist/packages/player/src/composition/renditionFrames.js +160 -0
  242. package/dist/packages/player/src/controls/ChoiceMenu.js +125 -0
  243. package/dist/packages/player/src/controls/FullscreenButton.js +29 -0
  244. package/dist/packages/player/src/controls/MotionLookButton.js +34 -0
  245. package/dist/packages/player/src/controls/PictureMenus.js +60 -0
  246. package/dist/packages/player/src/controls/SeekBar.js +126 -0
  247. package/dist/packages/player/src/controls/SoundControls.js +43 -0
  248. package/dist/packages/player/src/controls/TransportButtons.js +28 -0
  249. package/dist/packages/player/src/controls/ViewGestures.js +135 -0
  250. package/dist/packages/player/src/controls/Wording.js +79 -0
  251. package/dist/packages/player/src/controls/controlParts.js +38 -0
  252. package/dist/packages/player/src/controls/controls.js +4 -0
  253. package/dist/packages/player/src/controls/controlsBar.js +33 -0
  254. package/dist/packages/player/src/controls/controlsMarkup.js +100 -0
  255. package/dist/packages/player/src/controls/customControls.js +43 -0
  256. package/dist/packages/player/src/controls/formatTime.js +19 -0
  257. package/dist/packages/player/src/controls/icons.js +66 -0
  258. package/dist/packages/player/src/controls/keyboard.js +120 -0
  259. package/dist/packages/player/src/controls/messages.js +130 -0
  260. package/dist/packages/player/src/controls/nativeFullscreen.js +27 -0
  261. package/dist/packages/player/src/controls/parseMarkup.js +30 -0
  262. package/dist/packages/player/src/controls/resetViewButton.js +11 -0
  263. package/dist/packages/player/src/controls/sliderFill.js +15 -0
  264. package/dist/packages/player/src/element/ElementLoads.js +130 -0
  265. package/dist/packages/player/src/element/FullscreenToggle.js +93 -0
  266. package/dist/packages/player/src/element/GyroViewElement.js +358 -0
  267. package/dist/packages/player/src/element/IdleWatcher.js +71 -0
  268. package/dist/packages/player/src/element/PlayerCanvas.js +72 -0
  269. package/dist/packages/player/src/element/TypedEventElement.js +22 -0
  270. package/dist/packages/player/src/element/accessibleRegion.js +19 -0
  271. package/dist/packages/player/src/element/attributeNames.js +62 -0
  272. package/dist/packages/player/src/element/attributes.js +123 -0
  273. package/dist/packages/player/src/element/defineGyroView.js +20 -0
  274. package/dist/packages/player/src/element/earlyProperties.js +35 -0
  275. package/dist/packages/player/src/element/elementProperties.js +34 -0
  276. package/dist/packages/player/src/element/elementSource.js +39 -0
  277. package/dist/packages/player/src/element/fetchProperty.js +48 -0
  278. package/dist/packages/player/src/element/liveSettings.js +137 -0
  279. package/dist/packages/player/src/element/playbackAttributes.js +52 -0
  280. package/dist/packages/player/src/element/playerEventMirror.js +33 -0
  281. package/dist/packages/player/src/element/reflectedProperties.js +96 -0
  282. package/dist/packages/player/src/element/styles.js +4 -0
  283. package/dist/packages/player/src/element/template.js +46 -0
  284. package/dist/packages/player/src/inspectRecording.js +21 -0
  285. package/dist/packages/player/src/player/FrameLoop.js +35 -0
  286. package/dist/packages/player/src/player/MotionLook.js +150 -0
  287. package/dist/packages/player/src/player/PictureSettings.js +59 -0
  288. package/dist/packages/player/src/player/PlaybackStarts.js +38 -0
  289. package/dist/packages/player/src/player/Player.js +379 -0
  290. package/dist/packages/player/src/player/PlayerEvents.js +28 -0
  291. package/dist/packages/player/src/player/PlayerPhase.js +38 -0
  292. package/dist/packages/player/src/player/PlayerSound.js +60 -0
  293. package/dist/packages/player/src/player/PlayerView.js +143 -0
  294. package/dist/packages/player/src/player/SessionRelay.js +74 -0
  295. package/dist/packages/player/src/player/StatusAnnouncer.js +29 -0
  296. package/dist/packages/player/src/player/ensureFinite.js +26 -0
  297. package/dist/packages/player/src/player/loadRecording.js +47 -0
  298. package/dist/packages/player/src/player/transportEvents.js +30 -0
  299. package/dist/packages/player/src/player/viewAngles.js +17 -0
  300. package/dist/packages/player/src/rendition.js +52 -0
  301. package/dist/standalone.js +5633 -0
  302. package/package.json +70 -3
@@ -0,0 +1,379 @@
1
+ import { degrees } from "../../../core/src/shared/units/angle.js";
2
+ import { asGyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
3
+ import { seconds } from "../../../core/src/shared/units/time.js";
4
+ import { Outbox } from "../../../core/src/shared/events/Outbox.js";
5
+ import { isFlowing } from "../../../core/src/domain/playback/PlayerState.js";
6
+ import { TypedEmitter } from "../../../core/src/shared/events/TypedEmitter.js";
7
+ import { ensureFinite, viewStateOf } from "./ensureFinite.js";
8
+ import { NO_ATTITUDE_SENSOR } from "../composition/attitudeSensor.js";
9
+ import { cssSizeOf } from "../composition/DrawingBufferFit.js";
10
+ import { FrameLoop } from "./FrameLoop.js";
11
+ import { loadRecording } from "./loadRecording.js";
12
+ import { MotionLook } from "./MotionLook.js";
13
+ import { IDLE, loadingPhase, sessionToPlay, statusOf } from "./PlayerPhase.js";
14
+ import { PictureSettings } from "./PictureSettings.js";
15
+ import { PlaybackStarts } from "./PlaybackStarts.js";
16
+ import { PlayerSound } from "./PlayerSound.js";
17
+ import { anglesOf } from "./viewAngles.js";
18
+ import { PlayerView } from "./PlayerView.js";
19
+ import { SessionRelay } from "./SessionRelay.js";
20
+ import { StatusAnnouncer } from "./StatusAnnouncer.js";
21
+ //#region ../../packages/player/src/player/Player.ts
22
+ /**
23
+ * The player without the element, which `createBrowserPlayer` gives: it plays one recording at a
24
+ * time on the canvas and audio element it was handed, reports in media-element events, and keeps
25
+ * its settings (view, view mode, motion look, stabilization, gain matching, sound, loop) from
26
+ * load to load. `<gyro-view>` is a facade over it.
27
+ */
28
+ var Player = class {
29
+ parts;
30
+ /**
31
+ * What the player announces, to listen to: only the player and its parts emit.
32
+ */
33
+ events;
34
+ emitter = new TypedEmitter();
35
+ /**
36
+ * What the player and its parts announce, heard once each change is whole (ADR 0021).
37
+ */
38
+ outbox = new Outbox(this.emitter);
39
+ statuses = new StatusAnnouncer(this.outbox, this.emitter);
40
+ loop;
41
+ phase = IDLE;
42
+ viewing;
43
+ motion;
44
+ picture = new PictureSettings(this.outbox);
45
+ /**
46
+ * A seek asked for before a recording was ready, where the next one starts.
47
+ */
48
+ pendingStartTime;
49
+ sound;
50
+ relay = new SessionRelay({
51
+ events: this.outbox,
52
+ onState: () => {
53
+ this.statuses.announce(this.status);
54
+ }
55
+ });
56
+ starts = new PlaybackStarts(this.outbox, () => this.play());
57
+ /**
58
+ * Whether the recording plays again from the start at its end; kept across loads.
59
+ */
60
+ shouldLoop = false;
61
+ /**
62
+ * Past `dispose`: a listener of the idle it announces must not load again.
63
+ */
64
+ isDisposed = false;
65
+ /**
66
+ * @internal A page gets its player from `createBrowserPlayer`, which composes the parts.
67
+ */
68
+ constructor(parts) {
69
+ this.parts = parts;
70
+ this.events = this.emitter;
71
+ this.loop = new FrameLoop(this.tick);
72
+ parts.host.audio.addEventListener("ended", this.tick);
73
+ this.sound = new PlayerSound(parts.host.audio, this.outbox);
74
+ this.viewing = new PlayerView(this.outbox, () => cssSizeOf(parts.host.canvas));
75
+ this.motion = new MotionLook({
76
+ sensor: parts.attitude ?? NO_ATTITUDE_SENSOR,
77
+ view: this.viewing,
78
+ events: this.outbox,
79
+ hasRecording: () => this.loaded !== void 0
80
+ });
81
+ }
82
+ get status() {
83
+ return statusOf(this.phase);
84
+ }
85
+ get metadata() {
86
+ return this.loaded?.opened.metadata;
87
+ }
88
+ get currentTime() {
89
+ return this.loaded?.pipeline.session.currentTime ?? seconds(0);
90
+ }
91
+ get duration() {
92
+ return this.loaded?.opened.duration ?? seconds(0);
93
+ }
94
+ /**
95
+ * False while playing or holding for frames, as a media element's `paused`.
96
+ */
97
+ get isPaused() {
98
+ return !isFlowing(this.loaded?.pipeline.session.state);
99
+ }
100
+ get view() {
101
+ return anglesOf(this.viewing.current);
102
+ }
103
+ get viewMode() {
104
+ return this.viewing.viewMode;
105
+ }
106
+ /**
107
+ * Whether a drag moves the picture as it is framed now; the view mode decides.
108
+ */
109
+ get canPan() {
110
+ return this.viewing.canPan;
111
+ }
112
+ /**
113
+ * Whether turning the device turns the normal view: `unavailable` where the device reports no
114
+ * attitude or access was refused.
115
+ */
116
+ get motionLook() {
117
+ return this.motion.state;
118
+ }
119
+ get stabilization() {
120
+ return this.picture.stabilization;
121
+ }
122
+ get quality() {
123
+ return this.picture.quality;
124
+ }
125
+ get isLooping() {
126
+ return this.shouldLoop;
127
+ }
128
+ get volume() {
129
+ return this.sound.volume;
130
+ }
131
+ get isMuted() {
132
+ return this.sound.isMuted;
133
+ }
134
+ /**
135
+ * Whether `setVolume` changes anything on this platform; iOS leaves media at the device's volume.
136
+ */
137
+ get canSetVolume() {
138
+ return this.sound.canSetVolume;
139
+ }
140
+ /**
141
+ * Replaces whatever was loaded. Resolves once the recording is ready, `autoplay` starting it
142
+ * then, a refusal a warning; rejects with the failure after reporting it as an `error` event.
143
+ * A load that a newer load or `unload` supersedes resolves quietly.
144
+ */
145
+ async load(source, options = {}) {
146
+ if (this.isDisposed) return;
147
+ const loading = this.outbox.change(() => {
148
+ this.unload();
149
+ const next = loadingPhase();
150
+ this.phase = next;
151
+ this.statuses.announce(this.status);
152
+ return next;
153
+ });
154
+ try {
155
+ await this.complete(loading, source, options);
156
+ } catch (error) {
157
+ if (loading.controller.signal.aborted) return;
158
+ throw this.failWith(error);
159
+ } finally {
160
+ loading.settled.resolve();
161
+ }
162
+ }
163
+ unload() {
164
+ this.outbox.change(() => {
165
+ this.release();
166
+ this.statuses.announce(this.status);
167
+ });
168
+ }
169
+ /**
170
+ * Starts playback, after a load in progress is ready, and resolves once it runs, as a media
171
+ * element's `play()` does. Rejects with the load's failure, with `playback-blocked` when the
172
+ * browser wants a user gesture first, with `no-source` when nothing is loaded or loading, and
173
+ * with `play-interrupted` when a newer load or `unload` replaced the load it waited for.
174
+ */
175
+ async play() {
176
+ const waitedFor = this.phase.kind === "loading" ? this.phase : void 0;
177
+ await waitedFor?.settled.promise;
178
+ await sessionToPlay(this.phase, waitedFor).play();
179
+ }
180
+ pause() {
181
+ this.loaded?.pipeline.session.pause();
182
+ }
183
+ /**
184
+ * Pauses, or starts playing and reports a refused start as a `warning`: what a tap on the
185
+ * picture or a play button does.
186
+ */
187
+ togglePlayback() {
188
+ if (this.isPaused) this.starts.press();
189
+ else this.pause();
190
+ }
191
+ stop() {
192
+ this.loaded?.pipeline.session.stop();
193
+ }
194
+ /**
195
+ * Seeks exactly to `time` seconds; while a recording is loading, before one is, or after its
196
+ * playback failed, the next one starts there, as a media element's default playback start
197
+ * position has it.
198
+ */
199
+ seek(time) {
200
+ ensureFinite(time, "time");
201
+ const session = this.loaded?.pipeline.session;
202
+ if (session && session.state !== "error") session.seek(seconds(time));
203
+ else this.pendingStartTime = seconds(time);
204
+ }
205
+ /**
206
+ * Seeks to the key frame at or before `time` seconds: quick to show while a seek bar is dragged.
207
+ */
208
+ async scrub(time) {
209
+ ensureFinite(time, "time");
210
+ await this.loaded?.pipeline.session.scrub(seconds(time));
211
+ }
212
+ setView(view) {
213
+ this.viewing.set(viewStateOf(view));
214
+ }
215
+ /**
216
+ * Points the normal view at `yaw` and `pitch`, in degrees: yaw positive to the right, pitch
217
+ * positive up.
218
+ */
219
+ lookAt(yaw, pitch) {
220
+ ensureFinite(yaw, "yaw");
221
+ ensureFinite(pitch, "pitch");
222
+ this.viewing.lookAt(degrees(yaw), degrees(pitch));
223
+ }
224
+ /**
225
+ * The viewer dragged the picture by `delta` CSS pixels across the canvas.
226
+ */
227
+ pan(delta) {
228
+ this.viewing.pan(delta);
229
+ }
230
+ /**
231
+ * The viewer turned by the given angles in degrees, as the arrow keys do.
232
+ */
233
+ turn(yawDelta, pitchDelta) {
234
+ ensureFinite(yawDelta, "yaw turn");
235
+ ensureFinite(pitchDelta, "pitch turn");
236
+ this.viewing.turn(degrees(yawDelta), degrees(pitchDelta));
237
+ }
238
+ /**
239
+ * Zooms by `steps` (positive zooms in) toward `focus`, a point of the canvas as fractions of its
240
+ * size; about the centre when none is given.
241
+ */
242
+ zoom(steps, focus) {
243
+ ensureFinite(steps, "zoom steps");
244
+ this.viewing.zoom(steps, focus);
245
+ }
246
+ resetView() {
247
+ this.viewing.reset();
248
+ }
249
+ setViewMode(mode) {
250
+ this.viewing.setMode(mode);
251
+ this.motion.reconsider();
252
+ }
253
+ /**
254
+ * Lets the device turn the normal view, as a window into the recording: its tilt and roll
255
+ * hold the pitch and keep the horizon level, drags turn the heading alone. Call it from a tap's
256
+ * handler: iOS asks the viewer for access there and refuses it anywhere else. Resolves with the
257
+ * state it ends in; a refusal is a warning, never a rejection.
258
+ */
259
+ startMotionLook() {
260
+ return this.motion.start();
261
+ }
262
+ /**
263
+ * Gives the view back to the pointer, level, looking where it looked.
264
+ */
265
+ stopMotionLook() {
266
+ this.motion.stop();
267
+ }
268
+ setStabilization(mode) {
269
+ this.picture.setStabilization(mode);
270
+ }
271
+ /**
272
+ * How finely the lens images are read and how many device pixels are drawn; kept across loads.
273
+ */
274
+ setQuality(quality) {
275
+ this.picture.setQuality(quality);
276
+ }
277
+ setLooping(isLooping) {
278
+ this.shouldLoop = isLooping;
279
+ this.loaded?.pipeline.session.setLooping(isLooping);
280
+ }
281
+ /**
282
+ * Whether the lenses' exposure is matched along the seam; kept across loads.
283
+ */
284
+ setGainMatching(isEnabled) {
285
+ this.picture.setGainMatching(isEnabled);
286
+ }
287
+ setVolume(volume) {
288
+ ensureFinite(volume, "volume");
289
+ this.sound.setVolume(volume);
290
+ }
291
+ setMuted(isMuted) {
292
+ this.sound.setMuted(isMuted);
293
+ }
294
+ dispose() {
295
+ this.isDisposed = true;
296
+ this.unload();
297
+ this.motion.dispose();
298
+ this.parts.host.audio.removeEventListener("ended", this.tick);
299
+ this.sound.dispose();
300
+ this.emitter.removeAll();
301
+ }
302
+ tick = () => {
303
+ this.loaded?.pipeline.session.tick();
304
+ };
305
+ get loaded() {
306
+ return this.phase.kind === "loaded" ? this.phase.loaded : void 0;
307
+ }
308
+ async complete(loading, source, options) {
309
+ const { signal } = loading.controller;
310
+ const loaded = await loadRecording({
311
+ source,
312
+ parts: this.parts,
313
+ signal
314
+ });
315
+ if (signal.aborted) {
316
+ loaded.dispose();
317
+ return;
318
+ }
319
+ this.outbox.change(() => {
320
+ this.attach(loaded, loading.controller);
321
+ this.startAtPendingTime(loaded);
322
+ if (options.preload !== false) loaded.pipeline.session.preload();
323
+ });
324
+ if (options.autoplay && this.loaded === loaded) this.starts.autoplay();
325
+ }
326
+ startAtPendingTime(loaded) {
327
+ const time = this.pendingStartTime;
328
+ this.pendingStartTime = void 0;
329
+ if (time !== void 0) loaded.pipeline.session.seek(time);
330
+ }
331
+ attach(loaded, controller) {
332
+ this.phase = {
333
+ kind: "loaded",
334
+ loaded,
335
+ controller
336
+ };
337
+ this.viewing.attach(loaded.pipeline.renderer);
338
+ this.motion.reconsider();
339
+ const { session } = loaded.pipeline;
340
+ session.setLooping(this.shouldLoop);
341
+ this.picture.attach(loaded.pipeline);
342
+ this.relay.attach(session);
343
+ this.loop.start();
344
+ this.statuses.announce(this.status);
345
+ for (const warning of loaded.warnings) this.outbox.emit("warning", warning);
346
+ this.outbox.emit("ready", loaded.opened.metadata);
347
+ }
348
+ /**
349
+ * Lets go of whatever is loading or loaded, announcing nothing.
350
+ */
351
+ release() {
352
+ const previous = this.phase;
353
+ this.phase = IDLE;
354
+ if (previous.kind === "loading") previous.controller.abort();
355
+ this.loop.stop();
356
+ this.relay.detach();
357
+ this.viewing.attach(void 0);
358
+ this.motion.reconsider();
359
+ this.picture.attach(void 0);
360
+ if (previous.kind !== "loaded") return;
361
+ previous.loaded.dispose();
362
+ previous.controller.abort();
363
+ }
364
+ failWith(error) {
365
+ const failure = asGyroViewError(error, "invariant-violation", "the player failed unexpectedly");
366
+ this.outbox.change(() => {
367
+ this.release();
368
+ this.phase = {
369
+ kind: "failed",
370
+ failure
371
+ };
372
+ this.statuses.announce(this.status);
373
+ this.outbox.emit("error", failure);
374
+ });
375
+ return failure;
376
+ }
377
+ };
378
+ //#endregion
379
+ export { Player };
@@ -0,0 +1,28 @@
1
+ import { keysOf } from "../../../core/src/shared/keysOf.js";
2
+ //#region ../../packages/player/src/player/PlayerEvents.ts
3
+ /**
4
+ * Every event name once.
5
+ */
6
+ var PLAYER_EVENT_NAMES = keysOf({
7
+ statuschange: true,
8
+ ready: true,
9
+ play: true,
10
+ playing: true,
11
+ waiting: true,
12
+ pause: true,
13
+ ended: true,
14
+ timeupdate: true,
15
+ seeking: true,
16
+ seeked: true,
17
+ frame: true,
18
+ viewchange: true,
19
+ viewmodechange: true,
20
+ motionlookchange: true,
21
+ stabilizationchange: true,
22
+ qualitychange: true,
23
+ volumechange: true,
24
+ warning: true,
25
+ error: true
26
+ });
27
+ //#endregion
28
+ export { PLAYER_EVENT_NAMES };
@@ -0,0 +1,38 @@
1
+ import { GyroViewError } from "../../../core/src/shared/errors/GyroViewError.js";
2
+ import { Deferred } from "../../../core/src/shared/async/Deferred.js";
3
+ //#region ../../packages/player/src/player/PlayerPhase.ts
4
+ var IDLE = { kind: "idle" };
5
+ function loadingPhase() {
6
+ return {
7
+ kind: "loading",
8
+ controller: new AbortController(),
9
+ settled: new Deferred()
10
+ };
11
+ }
12
+ /**
13
+ * A loaded recording's status is its session's state, `seeking` until a seek's picture is drawn.
14
+ */
15
+ function statusOf(phase) {
16
+ switch (phase.kind) {
17
+ case "idle": return "idle";
18
+ case "loading": return "loading";
19
+ case "loaded": {
20
+ const { session } = phase.loaded.pipeline;
21
+ return session.isSeeking ? "seeking" : session.state;
22
+ }
23
+ case "failed": return "error";
24
+ }
25
+ }
26
+ /**
27
+ * The session a `play` starts once the load it waited for, if it waited, has settled: the one
28
+ * loaded, by that load. A failure is the load's; a load replaced meanwhile interrupts the play,
29
+ * as a newer load interrupts a media element's.
30
+ */
31
+ function sessionToPlay(phase, waitedFor) {
32
+ if (phase.kind === "failed") throw phase.failure;
33
+ if (waitedFor !== void 0 && (phase.kind !== "loaded" || phase.controller !== waitedFor.controller)) throw new GyroViewError("play-interrupted", "a newer load or an unload replaced the load to play");
34
+ if (phase.kind !== "loaded") throw new GyroViewError("no-source", "there is no recording to play");
35
+ return phase.loaded.pipeline.session;
36
+ }
37
+ //#endregion
38
+ export { IDLE, loadingPhase, sessionToPlay, statusOf };
@@ -0,0 +1,60 @@
1
+ import { clamp } from "../../../core/src/shared/math/clamp.js";
2
+ //#region ../../packages/player/src/player/PlayerSound.ts
3
+ /**
4
+ * The sound, on the audio element the host lends: its volume and mute, kept across loads by the
5
+ * element itself and announced whoever changes them (the controls, the keyboard, a script, the
6
+ * browser's own media keys).
7
+ */
8
+ var PlayerSound = class {
9
+ audio;
10
+ events;
11
+ /**
12
+ * Whether the platform lets a page set the volume: iOS keeps media at the device's volume and
13
+ * ignores the setting, where a volume slider would move and change nothing.
14
+ */
15
+ canSetVolume;
16
+ constructor(audio, events) {
17
+ this.audio = audio;
18
+ this.events = events;
19
+ this.canSetVolume = isVolumeSettable(audio.ownerDocument);
20
+ audio.addEventListener("volumechange", this.onVolumeChange);
21
+ }
22
+ get volume() {
23
+ return this.audio.volume;
24
+ }
25
+ get isMuted() {
26
+ return this.audio.muted;
27
+ }
28
+ /**
29
+ * From 0 (silent) to 1 (as recorded); anything outside is clamped.
30
+ */
31
+ setVolume(volume) {
32
+ this.audio.volume = clamp(volume, 0, 1);
33
+ }
34
+ setMuted(isMuted) {
35
+ this.audio.muted = isMuted;
36
+ }
37
+ dispose() {
38
+ this.audio.removeEventListener("volumechange", this.onVolumeChange);
39
+ }
40
+ onVolumeChange = () => {
41
+ this.events.emit("volumechange", {
42
+ volume: this.volume,
43
+ isMuted: this.isMuted
44
+ });
45
+ };
46
+ };
47
+ /**
48
+ * A volume the probe sets, other than the default of 1.
49
+ */
50
+ var PROBE_VOLUME = .5;
51
+ /**
52
+ * Tried on an element of its own, so the one playing hears no volume change.
53
+ */
54
+ function isVolumeSettable(document) {
55
+ const probe = document.createElement("audio");
56
+ probe.volume = PROBE_VOLUME;
57
+ return probe.volume === PROBE_VOLUME;
58
+ }
59
+ //#endregion
60
+ export { PlayerSound };
@@ -0,0 +1,143 @@
1
+ import { DEFAULT_VIEW_MODE } from "../../../core/src/domain/view/ViewMode.js";
2
+ import { SCREEN_CENTRE } from "../../../core/src/domain/view/screenLayout.js";
3
+ import { lookAt } from "../../../core/src/domain/view/viewGestures.js";
4
+ import { DEFAULT_FRAMING, isSameFraming } from "../../../core/src/domain/view/Framing.js";
5
+ import { followReading, withoutRoll } from "../../../core/src/domain/view/motionLookView.js";
6
+ import { motionLookRulesFor, viewModeRulesFor } from "../../../core/src/domain/view/viewModes.js";
7
+ import { anglesOf, isSameAngles } from "./viewAngles.js";
8
+ //#region ../../packages/player/src/player/PlayerView.ts
9
+ /**
10
+ * Every layout the player accepts has two lenses; a renderer attached says so itself.
11
+ */
12
+ var LENS_COUNT_BEFORE_A_LOAD = 2;
13
+ /**
14
+ * How the picture is framed and which view mode shows it: kept across loads, drawn by whichever
15
+ * renderer is attached, and the normal view's angles announced when they change. The viewer's
16
+ * gestures and a host setting the view go through the mode's rules on the viewport as it is
17
+ * now; while the device holds the view (motion look, ADR 0040), through the rules it follows
18
+ * then.
19
+ */
20
+ var PlayerView = class {
21
+ events;
22
+ measureViewport;
23
+ framing = DEFAULT_FRAMING;
24
+ mode = DEFAULT_VIEW_MODE;
25
+ surface;
26
+ lensCount = LENS_COUNT_BEFORE_A_LOAD;
27
+ /**
28
+ * The device reading the held view follows from; none while the device does not hold it.
29
+ */
30
+ previous;
31
+ constructor(events, measureViewport) {
32
+ this.events = events;
33
+ this.measureViewport = measureViewport;
34
+ }
35
+ get current() {
36
+ return this.framing.view;
37
+ }
38
+ get viewMode() {
39
+ return this.mode;
40
+ }
41
+ /**
42
+ * Whether a drag moves the picture as it is framed now.
43
+ */
44
+ get canPan() {
45
+ return this.rules().canPan(this.framing);
46
+ }
47
+ /**
48
+ * Whether the device may turn the view in the current mode.
49
+ */
50
+ get followsDevice() {
51
+ return motionLookRulesFor(this.mode) !== void 0;
52
+ }
53
+ /**
54
+ * The renderer of the loaded recording, or nothing between loads. A new renderer draws the
55
+ * framing as it is now, however it changed while the recording was loading; the lens tiles are
56
+ * measured by the lenses it draws from then on.
57
+ */
58
+ attach(surface) {
59
+ this.surface = surface;
60
+ if (surface) this.lensCount = surface.lensCount;
61
+ surface?.setViewMode(this.mode);
62
+ surface?.setFraming(this.framing);
63
+ }
64
+ set(view) {
65
+ this.frame(this.rules().place(this.framing, view));
66
+ }
67
+ setMode(mode) {
68
+ if (mode === this.mode) return;
69
+ this.mode = mode;
70
+ this.surface?.setViewMode(mode);
71
+ this.events.emit("viewmodechange", mode);
72
+ }
73
+ lookAt(yaw, pitch) {
74
+ this.frame(this.rules().place(this.framing, lookAt(this.framing.view, yaw, pitch)));
75
+ }
76
+ /**
77
+ * Turns the view as the device turned: from its first reading on, the device holds the view.
78
+ */
79
+ followDevice(reading) {
80
+ const hold = followReading(this.framing.view, this.previous, reading);
81
+ this.previous = hold.reading;
82
+ this.frame({
83
+ ...this.framing,
84
+ view: hold.view
85
+ });
86
+ }
87
+ /**
88
+ * The device no longer holds the view: it stays where it looks, level again.
89
+ */
90
+ letGo() {
91
+ if (!this.previous) return;
92
+ this.previous = void 0;
93
+ this.frame({
94
+ ...this.framing,
95
+ view: withoutRoll(this.framing.view)
96
+ });
97
+ }
98
+ pan(delta) {
99
+ this.frame(this.rules().pan(this.framing, delta, this.context()));
100
+ }
101
+ turn(yaw, pitch) {
102
+ this.frame(this.rules().turn(this.framing, {
103
+ yaw,
104
+ pitch
105
+ }, this.context()));
106
+ }
107
+ /**
108
+ * Zooms by `steps`, keeping the point of the viewport at `focus` on what it shows.
109
+ */
110
+ zoom(steps, focus = SCREEN_CENTRE) {
111
+ this.frame(this.rules().zoom(this.framing, {
112
+ steps,
113
+ focus
114
+ }, this.context()));
115
+ }
116
+ /**
117
+ * Back to how the current mode starts; the other modes keep their framing.
118
+ */
119
+ reset() {
120
+ this.frame(this.rules().reset(this.framing));
121
+ }
122
+ /**
123
+ * Draws any change; announces one of the angles a page sees, not a roll alone.
124
+ */
125
+ frame(next) {
126
+ if (isSameFraming(next, this.framing)) return;
127
+ const haveAnglesChanged = !isSameAngles(next.view, this.framing.view);
128
+ this.framing = next;
129
+ this.surface?.setFraming(next);
130
+ if (haveAnglesChanged) this.events.emit("viewchange", anglesOf(next.view));
131
+ }
132
+ context() {
133
+ return {
134
+ viewport: this.measureViewport(),
135
+ lensCount: this.lensCount
136
+ };
137
+ }
138
+ rules() {
139
+ return (this.previous === void 0 ? void 0 : motionLookRulesFor(this.mode)) ?? viewModeRulesFor(this.mode);
140
+ }
141
+ };
142
+ //#endregion
143
+ export { PlayerView };