@vincentt-xr/sdk 2.0.0-alpha.0 → 2.0.0-alpha.10

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 (879) hide show
  1. package/GROUNDING.md +8193 -111
  2. package/README.md +86 -52
  3. package/dist/CanonicalHeadFrame-D_0OzdB9.cjs +1 -0
  4. package/dist/CanonicalHeadFrame-DdUqF6Fv.js +1506 -0
  5. package/dist/DebuggerUI-CVuV-VJ5.cjs +1 -0
  6. package/dist/DebuggerUI-D-rcPa54.js +275 -0
  7. package/dist/FaceRetouch-C1AxBNex.js +1071 -0
  8. package/dist/FaceRetouch-D7kryDE6.cjs +134 -0
  9. package/dist/FaceSurface-CHAMEeG1.cjs +1 -0
  10. package/dist/FaceSurface-DmP9AEeC.js +27 -0
  11. package/dist/SkeletonUtils-C2r90MtN.js +21 -0
  12. package/dist/SkeletonUtils-CddIup1F.cjs +1 -0
  13. package/dist/TextLabel-XE0rQSDn.cjs +2 -0
  14. package/dist/TextLabel-c9BCucOI.js +961 -0
  15. package/dist/assets/cache.d.ts +99 -0
  16. package/dist/assets/estimate.d.ts +11 -0
  17. package/dist/assets/gltfLoader.d.ts +16 -0
  18. package/dist/assets/index.d.ts +7 -0
  19. package/dist/assets/loaders.d.ts +43 -0
  20. package/dist/assets/react.d.ts +33 -0
  21. package/dist/assets/sdkModels.d.ts +22 -0
  22. package/dist/audio/AudioEngine.d.ts +3 -1
  23. package/dist/audio/AudioPlayer.d.ts +29 -0
  24. package/dist/audio/AudioPlayerLogic.d.ts +4 -0
  25. package/dist/audio/index.d.ts +2 -0
  26. package/dist/body/__fixtures__/syntheticRig.d.ts +21 -0
  27. package/dist/body/bodyFlipGuard.d.ts +39 -0
  28. package/dist/body/bodyIdentity.d.ts +72 -0
  29. package/dist/body/bodyMask.d.ts +79 -0
  30. package/dist/body/bodyMaskMaterial.d.ts +15 -0
  31. package/dist/body/bodyPose.d.ts +58 -0
  32. package/dist/body/bodyRigFit.d.ts +148 -0
  33. package/dist/body/bodyRigSolver.d.ts +114 -0
  34. package/dist/body/bodySubject.d.ts +46 -0
  35. package/dist/body-pose/index.d.ts +521 -0
  36. package/dist/body-trigger/__fixtures__/syntheticBody.d.ts +83 -0
  37. package/dist/body-trigger/frame.d.ts +88 -0
  38. package/dist/body-trigger/index.d.ts +6 -0
  39. package/dist/body-trigger/moves.d.ts +235 -0
  40. package/dist/body-trigger/trigger.d.ts +75 -0
  41. package/dist/bodyMaskMaterial-CBWub5t_.cjs +68 -0
  42. package/dist/bodyMaskMaterial-Cs2awskk.js +207 -0
  43. package/dist/cache-2x3CUJuY.js +212 -0
  44. package/dist/cache-DL1Dbz6k.cjs +1 -0
  45. package/dist/calibration/calibration.d.ts +75 -0
  46. package/dist/calibration/index.d.ts +6 -0
  47. package/dist/calibration/storage.d.ts +13 -0
  48. package/dist/calibration/types.d.ts +53 -0
  49. package/dist/calibration/useXRCalibration.d.ts +46 -0
  50. package/dist/camera/CameraPermissionGate.d.ts +26 -0
  51. package/dist/camera/devices.d.ts +26 -0
  52. package/dist/camera/index.d.ts +8 -0
  53. package/dist/camera/permission.d.ts +86 -0
  54. package/dist/camera/useCameraPermission.d.ts +35 -0
  55. package/dist/canonicalFace-BHwyCx1c.js +9 -0
  56. package/dist/canonicalFace-C83I225R.cjs +1 -0
  57. package/dist/capabilities/detect.d.ts +45 -0
  58. package/dist/capabilities/index.d.ts +5 -0
  59. package/dist/capabilities/types.d.ts +120 -0
  60. package/dist/capabilities/useXRCapabilities.d.ts +18 -0
  61. package/dist/compat/environment.d.ts +5 -0
  62. package/dist/compat/index.d.ts +4 -0
  63. package/dist/compat/run.d.ts +18 -0
  64. package/dist/compat/scenarios.d.ts +10 -0
  65. package/dist/compat/types.d.ts +101 -0
  66. package/dist/components/Axes/index.d.ts +6 -0
  67. package/dist/components/BodyInstruction/BodyPoseHint.d.ts +63 -0
  68. package/dist/components/BodyInstruction/index.d.ts +76 -0
  69. package/dist/components/BodyInstruction/useBodyPose.d.ts +30 -0
  70. package/dist/components/BodyRig/BodyAttachment.d.ts +28 -0
  71. package/dist/components/BodyRig/BodyOccluder.d.ts +27 -0
  72. package/dist/components/BodyRig/bodyDepth.d.ts +57 -0
  73. package/dist/components/BodyRig/index.d.ts +129 -0
  74. package/dist/components/BodyRig/useBodyDepthTexture.d.ts +40 -0
  75. package/dist/components/BodyTracker/index.d.ts +26 -1
  76. package/dist/components/BodyTrigger/index.d.ts +56 -0
  77. package/dist/components/Debugger/DebuggerProvider.d.ts +14 -1
  78. package/dist/components/Debugger/DebuggerUI.d.ts +3 -1
  79. package/dist/components/FaceAtlas/FaceAtlasLayer.d.ts +114 -0
  80. package/dist/components/FaceAtlas/MadeUpCamera.d.ts +80 -0
  81. package/dist/components/FaceAtlas/constants.d.ts +8 -0
  82. package/dist/components/FaceAtlas/index.d.ts +7 -0
  83. package/dist/components/FaceAtlas/useFaceAtlasSurface.d.ts +84 -0
  84. package/dist/components/FaceAtlas/useFaceSkin.d.ts +84 -0
  85. package/dist/components/FaceCharacter/ExternalFaceMesh.d.ts +109 -0
  86. package/dist/components/FaceCharacter/FaceExpressionController.d.ts +53 -0
  87. package/dist/components/FaceCharacter/FaceMorph.d.ts +71 -0
  88. package/dist/components/FaceCharacter/FacePiercing.d.ts +65 -0
  89. package/dist/components/FaceCharacter/FaceReprojection.d.ts +85 -0
  90. package/dist/components/FaceCharacter/FaceRig.d.ts +38 -0
  91. package/dist/components/FaceCharacter/FaceSurface.d.ts +49 -0
  92. package/dist/components/FaceCharacter/FaceSurfaceOccluder.d.ts +39 -0
  93. package/dist/components/FaceCharacter/PinToFaceMesh.d.ts +68 -0
  94. package/dist/components/FaceCharacter/index.d.ts +18 -0
  95. package/dist/components/FaceCharacter/useFaceReprojector.d.ts +10 -0
  96. package/dist/components/FaceInset/FaceInset.d.ts +68 -0
  97. package/dist/components/FaceInset/frame.d.ts +94 -0
  98. package/dist/components/FaceInset/index.d.ts +6 -0
  99. package/dist/components/FaceInset/material.d.ts +40 -0
  100. package/dist/components/FaceInset/useFaceInsetTexture.d.ts +37 -0
  101. package/dist/components/FaceInstruction/FaceExpressionHint.d.ts +43 -0
  102. package/dist/components/FaceInstruction/index.d.ts +56 -0
  103. package/dist/components/FaceInstruction/useFaceExpression.d.ts +20 -0
  104. package/dist/components/FaceLiquify/FaceLiquify.d.ts +49 -0
  105. package/dist/components/FaceLiquify/debug.d.ts +37 -0
  106. package/dist/components/FaceLiquify/frame.d.ts +55 -0
  107. package/dist/components/FaceLiquify/index.d.ts +10 -0
  108. package/dist/components/FaceLiquify/material.d.ts +39 -0
  109. package/dist/components/FaceLiquify/pass.d.ts +49 -0
  110. package/dist/components/FaceLiquify/presence.d.ts +25 -0
  111. package/dist/components/FaceLiquify/presets.d.ts +82 -0
  112. package/dist/components/FaceLiquify/selfTest.d.ts +66 -0
  113. package/dist/components/FaceLiquify/target.d.ts +85 -0
  114. package/dist/components/FaceLiquify/warp.d.ts +72 -0
  115. package/dist/components/FaceMesh/FaceMeshRenderer.d.ts +25 -0
  116. package/dist/components/FaceMesh/canonical/CanonicalFaceMeshRenderer.d.ts +70 -1
  117. package/dist/components/FaceMesh/canonical/FaceMeshMaterial.d.ts +25 -0
  118. package/dist/components/FaceMesh/canonical/assets.d.ts +3 -0
  119. package/dist/components/FaceMesh/canonical/geometryGroups.d.ts +30 -0
  120. package/dist/components/FaceMesh/canonical/parseCanonicalFaceModel.d.ts +24 -0
  121. package/dist/components/FaceMesh/canonical/shaders.d.ts +2 -0
  122. package/dist/components/FaceMesh/deform.d.ts +3 -0
  123. package/dist/components/FaceMesh/index.d.ts +6 -1
  124. package/dist/components/FaceMesh/material/defaults.d.ts +74 -0
  125. package/dist/components/FaceMesh/material/index.d.ts +1 -0
  126. package/dist/components/FaceMesh/material/options.d.ts +5 -1
  127. package/dist/components/FaceMesh/material/support.d.ts +7 -2
  128. package/dist/components/FaceMesh/material/textures.d.ts +4 -0
  129. package/dist/components/FaceMesh/material/types.d.ts +4 -2
  130. package/dist/components/FaceRetouch/Background.d.ts +11 -5
  131. package/dist/components/FaceRetouch/FaceRetouch.d.ts +52 -0
  132. package/dist/components/FaceRetouch/index.d.ts +2 -6
  133. package/dist/components/FaceRetouch/landmarkMask.d.ts +4 -6
  134. package/dist/components/FaceRetouch/renderState.d.ts +19 -0
  135. package/dist/components/FaceRetouch/useFaceRetouchMask.d.ts +4 -7
  136. package/dist/components/FaceSwap/FaceMirror.d.ts +46 -0
  137. package/dist/components/FaceSwap/FaceSwap.d.ts +58 -0
  138. package/dist/components/FaceSwap/FaceTextureLayer.d.ts +72 -0
  139. package/dist/components/FaceSwap/faceSwapPlan.d.ts +91 -0
  140. package/dist/components/FaceSwap/index.d.ts +13 -0
  141. package/dist/components/FaceSwap/settings.d.ts +300 -0
  142. package/dist/components/FaceSwap/useFaceTexture.d.ts +35 -0
  143. package/dist/components/FaceSwap/useLiveFace.d.ts +38 -0
  144. package/dist/components/FaceSwap/useLiveFaceTexture.d.ts +31 -0
  145. package/dist/components/FaceTracker/index.d.ts +5 -3
  146. package/dist/components/FaceWarp3D/FaceWarp3D.d.ts +50 -0
  147. package/dist/components/FaceWarp3D/index.d.ts +2 -0
  148. package/dist/components/Faceless/Faceless.d.ts +51 -0
  149. package/dist/components/Faceless/index.d.ts +2 -0
  150. package/dist/components/GestureListener/index.d.ts +11 -0
  151. package/dist/components/HairLock/HairLock.d.ts +39 -0
  152. package/dist/components/HairLock/index.d.ts +2 -0
  153. package/dist/components/HairLock/lockGeometry.d.ts +15 -0
  154. package/dist/components/HandCutout/index.d.ts +35 -0
  155. package/dist/components/HandEffect/index.d.ts +36 -0
  156. package/dist/components/HandInstruction/HandGestureHint.d.ts +70 -0
  157. package/dist/components/HandInstruction/index.d.ts +74 -0
  158. package/dist/components/HandInstruction/useHandGesture.d.ts +22 -0
  159. package/dist/components/HandJoints2D/index.d.ts +6 -0
  160. package/dist/components/HandRig/ForearmOccluder.d.ts +29 -0
  161. package/dist/components/HandRig/HandAttachment.d.ts +34 -0
  162. package/dist/components/HandRig/HandNails.d.ts +61 -0
  163. package/dist/components/HandRig/HandOccluder.d.ts +45 -0
  164. package/dist/components/HandRig/HandTattoo.d.ts +61 -0
  165. package/dist/components/HandRig/WristAttachment.d.ts +34 -0
  166. package/dist/components/HandRig/index.d.ts +127 -0
  167. package/dist/components/HandRig/useArmMask.d.ts +29 -0
  168. package/dist/components/HandRig/wristSolve.d.ts +96 -0
  169. package/dist/components/HandTouch/HandTouch.d.ts +62 -0
  170. package/dist/components/HandTouch/Touchable.d.ts +36 -0
  171. package/dist/components/HandTouch/index.d.ts +2 -0
  172. package/dist/components/HandTracker/index.d.ts +12 -2
  173. package/dist/components/HandTracking2D/HandVisual.d.ts +12 -0
  174. package/dist/components/HandTracking2D/index.d.ts +5 -0
  175. package/dist/components/HandTracking2DController/index.d.ts +5 -0
  176. package/dist/components/HandTracking3D/index.d.ts +6 -0
  177. package/dist/components/HeadBinding/index.d.ts +14 -0
  178. package/dist/components/HeadOccluder/CanonicalHeadFrame.d.ts +22 -0
  179. package/dist/components/HeadOccluder/Earrings.d.ts +55 -0
  180. package/dist/components/HeadOccluder/HeadAttachment.d.ts +38 -0
  181. package/dist/components/HeadOccluder/NeckOccluder.d.ts +67 -0
  182. package/dist/components/HeadOccluder/earringPlacement.d.ts +31 -0
  183. package/dist/components/HeadOccluder/headAttachmentPoints.d.ts +69 -0
  184. package/dist/components/HeadOccluder/index.d.ts +57 -3
  185. package/dist/components/HeadOccluder/useCanonicalHeadFit.d.ts +36 -0
  186. package/dist/components/HeadOccluder/useLandmarkPoseFit.d.ts +80 -0
  187. package/dist/components/HolisticTracker/index.d.ts +69 -0
  188. package/dist/components/HolisticTracker/settings.d.ts +58 -0
  189. package/dist/components/HolisticTracker/signals.d.ts +49 -0
  190. package/dist/components/Instruction/HintStage.d.ts +29 -0
  191. package/dist/components/Instruction/InstructionCue.d.ts +126 -0
  192. package/dist/components/Instruction/gestureHold.d.ts +20 -0
  193. package/dist/components/Instruction/ghost.d.ts +129 -0
  194. package/dist/components/Instruction/hintBlend.d.ts +19 -0
  195. package/dist/components/Instruction/hintLook.d.ts +81 -0
  196. package/dist/components/Instruction/hintLoop.d.ts +36 -0
  197. package/dist/components/Instruction/index.d.ts +41 -0
  198. package/dist/components/Instruction/useGhostModel.d.ts +33 -0
  199. package/dist/components/Instruction/useInstructionHold.d.ts +72 -0
  200. package/dist/components/IrisEffect/IrisMaterial.d.ts +73 -0
  201. package/dist/components/IrisEffect/index.d.ts +51 -0
  202. package/dist/components/IrisEffect/settings.d.ts +117 -0
  203. package/dist/components/LightObject/index.d.ts +20 -0
  204. package/dist/components/LipEffect/LipEffect.d.ts +28 -0
  205. package/dist/components/LipEffect/LipEffectMaterial.d.ts +98 -0
  206. package/dist/components/LipEffect/LipEffects.d.ts +12 -0
  207. package/dist/components/LipEffect/defaults.d.ts +51 -0
  208. package/dist/components/LipEffect/index.d.ts +12 -0
  209. package/dist/components/LipEffect/lipShading.d.ts +73 -0
  210. package/dist/components/LipEffect/settings.d.ts +375 -0
  211. package/dist/components/LipEffect/shader.d.ts +39 -0
  212. package/dist/components/LipEffect/types.d.ts +141 -0
  213. package/dist/components/LipEffect/useLipDesignTextures.d.ts +17 -0
  214. package/dist/components/LipEffect/uvGuide.d.ts +74 -0
  215. package/dist/components/LookAt/index.d.ts +23 -0
  216. package/dist/components/Makeup/Blush.d.ts +18 -0
  217. package/dist/components/Makeup/Brows.d.ts +20 -0
  218. package/dist/components/Makeup/Contour.d.ts +17 -0
  219. package/dist/components/Makeup/Eyeliner.d.ts +20 -0
  220. package/dist/components/Makeup/Eyeshadow.d.ts +20 -0
  221. package/dist/components/Makeup/Highlighter.d.ts +18 -0
  222. package/dist/components/Makeup/MakeupDesign.d.ts +37 -0
  223. package/dist/components/Makeup/MakeupRegion.d.ts +132 -0
  224. package/dist/components/Makeup/constants.d.ts +44 -0
  225. package/dist/components/Makeup/design.d.ts +106 -0
  226. package/dist/components/Makeup/designSamples.d.ts +42 -0
  227. package/dist/components/Makeup/eyes.d.ts +114 -0
  228. package/dist/components/Makeup/fields.d.ts +10 -0
  229. package/dist/components/Makeup/geometry.d.ts +106 -0
  230. package/dist/components/Makeup/index.d.ts +26 -0
  231. package/dist/components/Makeup/looks.d.ts +28 -0
  232. package/dist/components/Makeup/material.d.ts +239 -0
  233. package/dist/components/Makeup/settings.d.ts +54 -0
  234. package/dist/components/Makeup/shades.d.ts +143 -0
  235. package/dist/components/Makeup/shapes.d.ts +27 -0
  236. package/dist/components/Makeup/skinTone.d.ts +135 -0
  237. package/dist/components/Makeup/types.d.ts +110 -0
  238. package/dist/components/Makeup/useMakeupSkinTone.d.ts +40 -0
  239. package/dist/components/MeshRenderer/index.d.ts +59 -0
  240. package/dist/components/Necklace/Necklace.d.ts +44 -0
  241. package/dist/components/Necklace/index.d.ts +1 -0
  242. package/dist/components/ParticleEmitter/ParticleEmitter.d.ts +69 -0
  243. package/dist/components/ParticleEmitter/index.d.ts +1 -0
  244. package/dist/components/PersonCutout/index.d.ts +46 -0
  245. package/dist/components/PersonCutout/personCutout.d.ts +16 -0
  246. package/dist/components/PersonCutout/personMask.d.ts +19 -0
  247. package/dist/components/PersonCutout/useBodyMaskTexture.d.ts +35 -0
  248. package/dist/components/PerspectiveCamera/index.d.ts +2 -8
  249. package/dist/components/PinToMesh/index.d.ts +47 -0
  250. package/dist/components/RenderGroupLayer/index.d.ts +6 -0
  251. package/dist/components/SceneObjectRenderer/index.d.ts +23 -0
  252. package/dist/components/Screen2D/ScreenTransformFrame.d.ts +11 -0
  253. package/dist/components/Screen2D/ScreenTransformHelpers.d.ts +19 -0
  254. package/dist/components/Screen2D/ScreenTransformInteraction.d.ts +18 -0
  255. package/dist/components/Screen2D/index.d.ts +5 -0
  256. package/dist/components/ScreenGlass/defaults.d.ts +3 -0
  257. package/dist/components/ScreenGlass/index.d.ts +5 -0
  258. package/dist/components/ScreenGlass/shaders.d.ts +2 -0
  259. package/dist/components/ScreenGlass/types.d.ts +10 -0
  260. package/dist/components/ScreenGradient/defaults.d.ts +5 -0
  261. package/dist/components/ScreenGradient/index.d.ts +5 -0
  262. package/dist/components/ScreenGradient/shaders.d.ts +2 -0
  263. package/dist/components/ScreenGradient/types.d.ts +19 -0
  264. package/dist/components/ScreenImage/ScreenImage.d.ts +4 -0
  265. package/dist/components/ScreenImage/components/DynamicTextureSync.d.ts +9 -0
  266. package/dist/components/ScreenImage/components/ScreenImageBody.d.ts +9 -0
  267. package/dist/components/ScreenImage/components/ScreenImageFrame.d.ts +9 -0
  268. package/dist/components/ScreenImage/components/ScreenImageTransformFrame.d.ts +9 -0
  269. package/dist/components/ScreenImage/fit.d.ts +52 -0
  270. package/dist/components/ScreenImage/index.d.ts +10 -0
  271. package/dist/components/ScreenImage/materials/ScreenImageBlendMaterial.d.ts +9 -0
  272. package/dist/components/ScreenImage/materials/ScreenImageMaskMaterial.d.ts +11 -0
  273. package/dist/components/ScreenImage/materials/ScreenImageMatcap.d.ts +3 -0
  274. package/dist/components/ScreenImage/source.d.ts +25 -0
  275. package/dist/components/ScreenImage/types.d.ts +64 -0
  276. package/dist/components/ScreenImage/utils/ScreenImageConstants.d.ts +9 -0
  277. package/dist/components/ScreenImage/utils/ScreenImageHelpers.d.ts +4 -0
  278. package/dist/components/ScreenShape/geometry.d.ts +5 -0
  279. package/dist/components/ScreenShape/index.d.ts +5 -0
  280. package/dist/components/ScreenShape/types.d.ts +54 -0
  281. package/dist/components/ScreenSpaceUI/ScreenTransformGuide.d.ts +15 -0
  282. package/dist/components/ScreenSpaceUI/ScreenTransformOverlayGuide.d.ts +9 -0
  283. package/dist/components/ScreenSpaceUI/index.d.ts +3 -0
  284. package/dist/components/ScreenText/components/ScreenTextBody.d.ts +2 -0
  285. package/dist/components/ScreenText/components/ScreenTextTransformFrame.d.ts +9 -0
  286. package/dist/components/ScreenText/constants.d.ts +5 -0
  287. package/dist/components/ScreenText/index.d.ts +6 -0
  288. package/dist/components/ScreenText/types.d.ts +31 -0
  289. package/dist/components/ScreenText/utils/ScreenTextHelpers.d.ts +14 -0
  290. package/dist/components/ScreenText/utils/ScreenTextMappings.d.ts +17 -0
  291. package/dist/components/SegmentationOverlay/SegmentationOverlay.d.ts +37 -0
  292. package/dist/components/SegmentationOverlay/SegmentationOverlayMaterial.d.ts +31 -0
  293. package/dist/components/SegmentationOverlay/index.d.ts +9 -0
  294. package/dist/components/SegmentationOverlay/maskTexture.d.ts +23 -0
  295. package/dist/components/SegmentationOverlay/providers.d.ts +72 -0
  296. package/dist/components/SegmentationOverlay/settings.d.ts +65 -0
  297. package/dist/components/SequentialRenderPasses/index.d.ts +6 -0
  298. package/dist/components/ShoulderOccluder/index.d.ts +46 -0
  299. package/dist/components/ShoulderOccluder/useCanonicalTorsoFit.d.ts +27 -0
  300. package/dist/components/SpringSwing/SpringSwing.d.ts +22 -0
  301. package/dist/components/SpringSwing/index.d.ts +1 -0
  302. package/dist/components/TextLabel/TextLabel.d.ts +5 -0
  303. package/dist/components/TextLabel/alignment.d.ts +4 -0
  304. package/dist/components/TextLabel/bend.d.ts +9 -0
  305. package/dist/components/TextLabel/canvas/buildTextLabelTexture.d.ts +4 -0
  306. package/dist/components/TextLabel/canvas/canvasTypography.d.ts +13 -0
  307. package/dist/components/TextLabel/canvas/drawBackground.d.ts +21 -0
  308. package/dist/components/TextLabel/canvas/drawEffects.d.ts +34 -0
  309. package/dist/components/TextLabel/canvas/drawText.d.ts +19 -0
  310. package/dist/components/TextLabel/components/TextLabelMesh.d.ts +13 -0
  311. package/dist/components/TextLabel/constants.d.ts +2 -0
  312. package/dist/components/TextLabel/hooks/useTextLabelTexture.d.ts +7 -0
  313. package/dist/components/TextLabel/index.d.ts +2 -62
  314. package/dist/components/TextLabel/layout/measurement.d.ts +8 -0
  315. package/dist/components/TextLabel/layout/resolveTextLayout.d.ts +25 -0
  316. package/dist/components/TextLabel/layout/wrapText.d.ts +6 -0
  317. package/dist/components/TextLabel/types.d.ts +337 -0
  318. package/dist/components/TrackingAnchor/index.d.ts +18 -2
  319. package/dist/components/Transform3D/index.d.ts +30 -0
  320. package/dist/components/XRMediaSurface/index.d.ts +8 -7
  321. package/dist/components/XRProvider/index.d.ts +16 -2
  322. package/dist/components/XRScene/index.d.ts +14 -3
  323. package/dist/components/XRScene/renderOutputTarget.d.ts +12 -0
  324. package/dist/components/XRViewport/XRViewport.d.ts +11 -0
  325. package/dist/components/XRViewport/components/HiddenMedia.d.ts +7 -0
  326. package/dist/components/XRViewport/components/MediaAssetPicker.d.ts +8 -0
  327. package/dist/components/XRViewport/components/MediaControlStack.d.ts +13 -0
  328. package/dist/components/XRViewport/components/XRViewportLayers.d.ts +30 -0
  329. package/dist/components/XRViewport/constants.d.ts +24 -0
  330. package/dist/components/XRViewport/contexts.d.ts +6 -0
  331. package/dist/components/XRViewport/hooks/useViewportExternalFaces.d.ts +13 -0
  332. package/dist/components/XRViewport/hooks/useViewportMediaSource.d.ts +16 -0
  333. package/dist/components/XRViewport/hooks/useViewportMediaTexture.d.ts +10 -0
  334. package/dist/components/XRViewport/hooks/useViewportPipeline.d.ts +41 -0
  335. package/dist/components/XRViewport/hooks/useViewportRenderState.d.ts +47 -0
  336. package/dist/components/XRViewport/index.d.ts +3 -101
  337. package/dist/components/XRViewport/layout.d.ts +16 -0
  338. package/dist/components/XRViewport/slots.d.ts +16 -0
  339. package/dist/components/XRViewport/types.d.ts +89 -0
  340. package/dist/components/XRViewport/useViewportSize.d.ts +3 -0
  341. package/dist/components/index.d.ts +31 -0
  342. package/dist/components/occluder/skinnedOccluder.d.ts +39 -0
  343. package/dist/config/index.d.ts +1 -1
  344. package/dist/constants/index.d.ts +4 -1
  345. package/dist/context-DTxSQvp4.js +13 -0
  346. package/dist/context-hA0Rb2Xa.cjs +1 -0
  347. package/dist/contexts-DQc7zyqT.cjs +1 -0
  348. package/dist/contexts-Y_FhdnIv.js +667 -0
  349. package/dist/coordinates/feed.d.ts +52 -0
  350. package/dist/coordinates/index.d.ts +7 -0
  351. package/dist/coordinates/side.d.ts +40 -0
  352. package/dist/coordinates/spaces.d.ts +49 -0
  353. package/dist/coordinates/viewport.d.ts +22 -0
  354. package/dist/coordinates/world.d.ts +15 -0
  355. package/dist/debug-ui/component-editor/index.d.ts +19 -0
  356. package/dist/debug-ui/default-setting/index.d.ts +37 -0
  357. package/dist/debug-ui/default-setting.cjs +21 -0
  358. package/dist/debug-ui/default-setting.js +777 -0
  359. package/dist/debug-ui/face-mesh-renderer-settings/index.d.ts +8 -0
  360. package/dist/debug-ui/face-retouch/index.d.ts +11 -0
  361. package/dist/debug-ui/face-swap-settings/index.d.ts +22 -0
  362. package/dist/debug-ui/gesture-settings/index.d.ts +14 -0
  363. package/dist/debug-ui/hand-joints-2d/index.d.ts +6 -0
  364. package/dist/debug-ui/hand-tracking-2d/index.d.ts +6 -0
  365. package/dist/debug-ui/hand-tracking-2d-controller/index.d.ts +6 -0
  366. package/dist/debug-ui/hand-tracking-3d/index.d.ts +6 -0
  367. package/dist/debug-ui/hierarchy-panel/index.d.ts +30 -0
  368. package/dist/debug-ui/holistic-tracker-settings/index.d.ts +16 -0
  369. package/dist/debug-ui/index.d.ts +61 -0
  370. package/dist/debug-ui/iris-effect-settings/index.d.ts +12 -0
  371. package/dist/debug-ui/layer-panel/index.d.ts +18 -0
  372. package/dist/debug-ui/lip-effect-settings/index.d.ts +15 -0
  373. package/dist/debug-ui/media-source/MediaSourceSwitcher.d.ts +10 -0
  374. package/dist/debug-ui/media-source/index.d.ts +6 -0
  375. package/dist/debug-ui/media-source/media-preset.d.ts +21 -0
  376. package/dist/debug-ui/media-source/session.d.ts +40 -0
  377. package/dist/debug-ui/media-source.cjs +1 -0
  378. package/dist/debug-ui/media-source.js +11 -0
  379. package/dist/debug-ui/mesh-renderer-settings/index.d.ts +6 -0
  380. package/dist/debug-ui/object-inspector-panel/index.d.ts +26 -0
  381. package/dist/debug-ui/pin-to-mesh-settings/index.d.ts +10 -0
  382. package/dist/debug-ui/product-hotspots/index.d.ts +25 -0
  383. package/dist/debug-ui/scene-editor/context.d.ts +38 -0
  384. package/dist/debug-ui/scene-editor/hierarchy-panel.d.ts +11 -0
  385. package/dist/debug-ui/scene-editor/index.d.ts +11 -0
  386. package/dist/debug-ui/scene-editor/inspector-panel.d.ts +9 -0
  387. package/dist/debug-ui/scene-editor/store-utils.d.ts +2 -0
  388. package/dist/debug-ui/scene-editor/viewport-toolbar.d.ts +4 -0
  389. package/dist/debug-ui/scene-editor/viewport.d.ts +21 -0
  390. package/dist/debug-ui/screen-glass-settings/index.d.ts +6 -0
  391. package/dist/debug-ui/screen-gradient-settings/GradientStopsEditor.d.ts +5 -0
  392. package/dist/debug-ui/screen-gradient-settings/index.d.ts +6 -0
  393. package/dist/debug-ui/screen-gradient-settings/styles.d.ts +3 -0
  394. package/dist/debug-ui/screen-image-settings/index.d.ts +11 -0
  395. package/dist/debug-ui/screen-shape-settings/index.d.ts +6 -0
  396. package/dist/debug-ui/screen-text-settings/NumberField.d.ts +9 -0
  397. package/dist/debug-ui/screen-text-settings/ScreenTextSettingsPanel.d.ts +3 -0
  398. package/dist/debug-ui/screen-text-settings/controls/NestedSection.d.ts +7 -0
  399. package/dist/debug-ui/screen-text-settings/controls/Section.d.ts +8 -0
  400. package/dist/debug-ui/screen-text-settings/controls/icons.d.ts +4 -0
  401. package/dist/debug-ui/screen-text-settings/index.d.ts +2 -0
  402. package/dist/debug-ui/screen-text-settings/sections/BackgroundSection.d.ts +8 -0
  403. package/dist/debug-ui/screen-text-settings/sections/ContentSection.d.ts +5 -0
  404. package/dist/debug-ui/screen-text-settings/sections/EffectsSection.d.ts +25 -0
  405. package/dist/debug-ui/screen-text-settings/sections/StyleSection.d.ts +5 -0
  406. package/dist/debug-ui/screen-text-settings/sections/TransformSection.d.ts +5 -0
  407. package/dist/debug-ui/screen-text-settings/sections/background/BackgroundFillControls.d.ts +2 -0
  408. package/dist/debug-ui/screen-text-settings/sections/background/BackgroundSizeControls.d.ts +2 -0
  409. package/dist/debug-ui/screen-text-settings/sections/background/BackgroundStrokeControls.d.ts +2 -0
  410. package/dist/debug-ui/screen-text-settings/sections/background/types.d.ts +7 -0
  411. package/dist/debug-ui/screen-text-settings/sections/effects/BendEffectSection.d.ts +4 -0
  412. package/dist/debug-ui/screen-text-settings/sections/effects/EffectChrome.d.ts +21 -0
  413. package/dist/debug-ui/screen-text-settings/sections/effects/GlowEffectSection.d.ts +4 -0
  414. package/dist/debug-ui/screen-text-settings/sections/effects/InnerShadowEffectSection.d.ts +4 -0
  415. package/dist/debug-ui/screen-text-settings/sections/effects/OutlineEffectSection.d.ts +4 -0
  416. package/dist/debug-ui/screen-text-settings/sections/effects/ShadowEffectSection.d.ts +4 -0
  417. package/dist/debug-ui/screen-text-settings/sections/effects/types.d.ts +14 -0
  418. package/dist/debug-ui/screen-text-settings/settings.d.ts +90 -0
  419. package/dist/debug-ui/screen-text-settings/styles.d.ts +26 -0
  420. package/dist/debug-ui/screen-text-settings/transform.d.ts +6 -0
  421. package/dist/debug-ui/screen-text-settings/types.d.ts +11 -0
  422. package/dist/debug-ui/segmentation-overlay-settings/index.d.ts +12 -0
  423. package/dist/debug-ui/settings-panel/index.d.ts +43 -0
  424. package/dist/debug-ui/shared/MaterialSection.d.ts +13 -0
  425. package/dist/debug-ui/shared/ScreenTransformSection.d.ts +32 -0
  426. package/dist/debug-ui/shared/debugWindow.d.ts +51 -0
  427. package/dist/debug-ui/transform-3d-settings/index.d.ts +11 -0
  428. package/dist/debug-ui/xr-diagnostics/index.d.ts +26 -0
  429. package/dist/debug-ui.cjs +10 -0
  430. package/dist/debug-ui.js +9051 -0
  431. package/dist/detector-K8aej4MB.js +59 -0
  432. package/dist/detector-ijypGtse.cjs +1 -0
  433. package/dist/drawNormalizedCrop-C4KFaRne.cjs +1 -0
  434. package/dist/drawNormalizedCrop-DG3gtJxf.js +135 -0
  435. package/dist/entries/all.d.ts +4 -1
  436. package/dist/entries/core.d.ts +76 -6
  437. package/dist/entries/face-effects.d.ts +130 -10
  438. package/dist/entries/instructions.d.ts +48 -0
  439. package/dist/entries/internal.d.ts +5 -2
  440. package/dist/entries/low-level.d.ts +104 -6
  441. package/dist/entries/particles.d.ts +15 -0
  442. package/dist/entries/product.d.ts +11 -0
  443. package/dist/entries/scene-object.d.ts +10 -0
  444. package/dist/entries/tracking.d.ts +110 -2
  445. package/dist/face-action/index.d.ts +34 -0
  446. package/dist/face-atlas/attributes.d.ts +30 -0
  447. package/dist/face-atlas/eyes.d.ts +272 -0
  448. package/dist/face-atlas/faceAtlas.generated.d.ts +46 -0
  449. package/dist/face-atlas/glsl/atlasVertex.d.ts +46 -0
  450. package/dist/face-atlas/glsl/common.d.ts +55 -0
  451. package/dist/face-atlas/glsl/design.d.ts +49 -0
  452. package/dist/face-atlas/glsl/eyes.d.ts +73 -0
  453. package/dist/face-atlas/glsl/finish.d.ts +24 -0
  454. package/dist/face-atlas/glsl/format.d.ts +4 -0
  455. package/dist/face-atlas/glsl/index.d.ts +59 -0
  456. package/dist/face-atlas/glsl/shading.d.ts +15 -0
  457. package/dist/face-atlas/glsl/shapes.d.ts +66 -0
  458. package/dist/face-atlas/glsl/sparkle.d.ts +19 -0
  459. package/dist/face-atlas/glsl/uniforms.d.ts +106 -0
  460. package/dist/face-atlas/guide.d.ts +51 -0
  461. package/dist/face-atlas/index.d.ts +25 -0
  462. package/dist/face-atlas/lead.d.ts +117 -0
  463. package/dist/face-atlas/madeUpCamera.d.ts +125 -0
  464. package/dist/face-atlas/masks.d.ts +53 -0
  465. package/dist/face-atlas/obj.d.ts +69 -0
  466. package/dist/face-atlas/polylines.d.ts +63 -0
  467. package/dist/face-atlas/probe/FaceSkinProbe.d.ts +208 -0
  468. package/dist/face-atlas/probe/__fixtures__/emulate.d.ts +9 -0
  469. package/dist/face-atlas/probe/__fixtures__/face.d.ts +24 -0
  470. package/dist/face-atlas/probe/constants.d.ts +137 -0
  471. package/dist/face-atlas/probe/glsl.d.ts +43 -0
  472. package/dist/face-atlas/probe/lightFit.d.ts +108 -0
  473. package/dist/face-atlas/probe/schedule.d.ts +44 -0
  474. package/dist/face-atlas/probe/selfTest.d.ts +87 -0
  475. package/dist/face-atlas/probe/stats.d.ts +143 -0
  476. package/dist/face-atlas/probe/targets.d.ts +70 -0
  477. package/dist/face-atlas/probe/unwrap.d.ts +76 -0
  478. package/dist/face-atlas/quality.d.ts +28 -0
  479. package/dist/face-atlas/regions.d.ts +31 -0
  480. package/dist/face-atlas/registry.d.ts +252 -0
  481. package/dist/face-atlas/renderState.d.ts +86 -0
  482. package/dist/face-atlas/selfOcclusion.d.ts +62 -0
  483. package/dist/face-atlas/shading.d.ts +406 -0
  484. package/dist/face-atlas/shapes.d.ts +86 -0
  485. package/dist/face-atlas/sides.d.ts +41 -0
  486. package/dist/face-atlas/skinMask.d.ts +35 -0
  487. package/dist/face-atlas/surface.d.ts +155 -0
  488. package/dist/face-atlas/topology.d.ts +44 -0
  489. package/dist/face-attribute-expression/index.d.ts +10 -0
  490. package/dist/face-character/__fixtures__/faceImageDetections.d.ts +25 -0
  491. package/dist/face-character/__fixtures__/faceNode.d.ts +22 -0
  492. package/dist/face-character/bindFaceModel.d.ts +106 -0
  493. package/dist/face-character/canonicalFace.d.ts +17 -0
  494. package/dist/face-character/canonicalFaceGeometry.d.ts +11 -0
  495. package/dist/face-character/canonicalFacePositions.d.ts +7 -0
  496. package/dist/face-character/driveFaceModel.d.ts +57 -0
  497. package/dist/face-character/expressionOutputs.d.ts +45 -0
  498. package/dist/face-character/faceExpressions.d.ts +104 -0
  499. package/dist/face-character/faceImageLandmarker.d.ts +93 -0
  500. package/dist/face-character/faceMeshBinding.d.ts +62 -0
  501. package/dist/face-character/faceMorph.d.ts +77 -0
  502. package/dist/face-character/faceMorphs.d.ts +46 -0
  503. package/dist/face-character/facePhoto.d.ts +138 -0
  504. package/dist/face-character/facePiercings.d.ts +116 -0
  505. package/dist/face-character/facePin.d.ts +131 -0
  506. package/dist/face-character/faceReprojection.d.ts +273 -0
  507. package/dist/face-character/faceReprojector.d.ts +171 -0
  508. package/dist/face-character/faceRig.d.ts +176 -0
  509. package/dist/face-character/faceSwapPresence.d.ts +85 -0
  510. package/dist/face-character/faceTexture.d.ts +169 -0
  511. package/dist/face-character/faceTextureBaker.d.ts +86 -0
  512. package/dist/face-character/faceTextureGuide.d.ts +106 -0
  513. package/dist/face-character/faceTextureStats.d.ts +298 -0
  514. package/dist/face-character/faceTransfer.d.ts +396 -0
  515. package/dist/face-character/faceTransferGeometry.d.ts +109 -0
  516. package/dist/face-character/faceTransferSelfTest.d.ts +94 -0
  517. package/dist/face-character/faceWarp3D.d.ts +101 -0
  518. package/dist/face-character/faceless.d.ts +79 -0
  519. package/dist/face-character/featureWarp.d.ts +28 -0
  520. package/dist/face-character/liveFaceRegistry.d.ts +370 -0
  521. package/dist/face-character/liveValue.d.ts +12 -0
  522. package/dist/face-character/memo.d.ts +15 -0
  523. package/dist/face-effects.cjs +2267 -195
  524. package/dist/face-effects.js +14191 -3346
  525. package/dist/face-expression/index.d.ts +182 -0
  526. package/dist/face-info/blendshapes.d.ts +3 -0
  527. package/dist/face-info/derive.d.ts +8 -0
  528. package/dist/face-info/drawFaceCrop.d.ts +10 -0
  529. package/dist/face-info/getFaceInfo.d.ts +8 -0
  530. package/dist/face-info/index.d.ts +8 -0
  531. package/dist/face-info/landmarks.d.ts +35 -0
  532. package/dist/face-info/types.d.ts +69 -0
  533. package/dist/gestures/definitions.d.ts +98 -0
  534. package/dist/gestures/detector.d.ts +87 -0
  535. package/dist/gestures/index.d.ts +8 -0
  536. package/dist/gestures/measures.d.ts +114 -0
  537. package/dist/gestures/settings.d.ts +49 -0
  538. package/dist/getFaceInfo-BafgGT27.js +62 -0
  539. package/dist/getFaceInfo-BzlwHMjX.cjs +1 -0
  540. package/dist/hand/armFit.d.ts +46 -0
  541. package/dist/hand/armMask.d.ts +190 -0
  542. package/dist/hand/forearm.d.ts +114 -0
  543. package/dist/hand/handCutout.d.ts +23 -0
  544. package/dist/hand/handCutoutRegistry.d.ts +7 -0
  545. package/dist/hand/handEffect.d.ts +38 -0
  546. package/dist/hand/handGestures.d.ts +524 -0
  547. package/dist/hand/handJoints2d.d.ts +49 -0
  548. package/dist/hand/handNail.d.ts +73 -0
  549. package/dist/hand/handPose.d.ts +98 -0
  550. package/dist/hand/handRigSolver.d.ts +159 -0
  551. package/dist/hand/handTattoo.d.ts +81 -0
  552. package/dist/hand/handTouch.d.ts +240 -0
  553. package/dist/hand/handTracking2d.d.ts +33 -0
  554. package/dist/hand/handTracking2dController.d.ts +65 -0
  555. package/dist/hand/handTracking3d.d.ts +52 -0
  556. package/dist/hand/nailImageMask.d.ts +40 -0
  557. package/dist/hand/nailMaskFingers.d.ts +23 -0
  558. package/dist/hand/nailTipRefine.d.ts +37 -0
  559. package/dist/hand/wrist.d.ts +44 -0
  560. package/dist/hand/wristFilter.d.ts +44 -0
  561. package/dist/hooks/faceResults.d.ts +1 -1
  562. package/dist/hooks/selectors.d.ts +77 -4
  563. package/dist/hooks/useBodies.d.ts +39 -0
  564. package/dist/hooks/useCalibrationFaceTracker.d.ts +1 -1
  565. package/dist/hooks/useFaceAction.d.ts +3 -0
  566. package/dist/hooks/useFaceAttributeExpression.d.ts +16 -0
  567. package/dist/hooks/useFaceDetection.d.ts +18 -0
  568. package/dist/hooks/useFaceInfo.d.ts +19 -0
  569. package/dist/hooks/useFaceInfos.d.ts +15 -0
  570. package/dist/hooks/useFaceModelAcquisition.d.ts +38 -0
  571. package/dist/hooks/useFaceResultReader.d.ts +10 -0
  572. package/dist/hooks/useFrameCapture.d.ts +18 -0
  573. package/dist/hooks/useGesture.d.ts +39 -0
  574. package/dist/hooks/useIrisTracking.d.ts +45 -0
  575. package/dist/hooks/useMediaRecorder.d.ts +14 -2
  576. package/dist/hooks/useOwnedTexture.d.ts +6 -0
  577. package/dist/hooks/useTrackerContext.d.ts +14 -2
  578. package/dist/hooks/useXRDiagnostics.d.ts +81 -0
  579. package/dist/hooks/useXRModel.d.ts +12 -0
  580. package/dist/hooks/useXRSession/facade.d.ts +47 -2
  581. package/dist/hooks/useXRSession/index.d.ts +2 -2
  582. package/dist/hooks/useXRSession/reason.d.ts +21 -0
  583. package/dist/hooks/useXRSession/registry.d.ts +23 -0
  584. package/dist/hooks/useXRSession/store.d.ts +64 -7
  585. package/dist/index-BZoBxyLn.js +1103 -0
  586. package/dist/index-By_LCo2V.cjs +1 -0
  587. package/dist/index-C-Mryx_u.cjs +21 -0
  588. package/dist/index-CKRN-xJp.js +3740 -0
  589. package/dist/index-CUldCMRl.js +188 -0
  590. package/dist/index-Cyk_VIZE.js +1432 -0
  591. package/dist/index-D-4w34GO.cjs +1 -0
  592. package/dist/index-DiIoHK_4.js +442 -0
  593. package/dist/index-Dv3WnY9n.cjs +46 -0
  594. package/dist/index-ItufYyHH.cjs +1 -0
  595. package/dist/index-S3gqudT6.cjs +1 -0
  596. package/dist/index-Sho4F4it.cjs +1 -0
  597. package/dist/index-iIQ9jBDb.js +240 -0
  598. package/dist/index-vr2ichWQ.js +190 -0
  599. package/dist/instructions.cjs +30 -0
  600. package/dist/instructions.js +1528 -0
  601. package/dist/internal-Bb9ZXbpr.cjs +1 -0
  602. package/dist/{internal-KOKJDxCG.js → internal-Gt1wn6Z3.js} +152 -127
  603. package/dist/internal.cjs +1 -1
  604. package/dist/internal.js +16 -9
  605. package/dist/iris/compute.d.ts +27 -0
  606. package/dist/iris/index.d.ts +4 -0
  607. package/dist/iris/lead.d.ts +19 -0
  608. package/dist/iris/types.d.ts +89 -0
  609. package/dist/landmarkMask-CvN-L5NT.cjs +1 -0
  610. package/dist/landmarkMask-DHivVjJm.js +225 -0
  611. package/dist/landmarks-BEjJXcnE.cjs +1 -0
  612. package/dist/landmarks-DtCAFV_m.js +76 -0
  613. package/dist/low-level.cjs +1 -1
  614. package/dist/low-level.js +1494 -629
  615. package/dist/main.cjs +1 -1
  616. package/dist/main.js +1306 -475
  617. package/dist/material/MaterialFill.d.ts +20 -0
  618. package/dist/material/MeshMaterial.d.ts +14 -0
  619. package/dist/material/index.d.ts +2 -0
  620. package/dist/models/Base/index.d.ts +49 -0
  621. package/dist/models/Body/index.d.ts +30 -1
  622. package/dist/models/Face/constants.d.ts +8 -0
  623. package/dist/models/Face/index.d.ts +5 -12
  624. package/dist/models/Face/rotation.d.ts +18 -0
  625. package/dist/models/Hand/GestureTracking.d.ts +1 -1
  626. package/dist/models/Hand/HandTracking.d.ts +19 -1
  627. package/dist/models/Holistic/index.d.ts +49 -0
  628. package/dist/models/Holistic/result.d.ts +68 -0
  629. package/dist/models/Segmentation/index.d.ts +6 -3
  630. package/dist/models/SemanticSegmentation/index.d.ts +31 -0
  631. package/dist/models/SemanticSegmentation/presets.d.ts +28 -0
  632. package/dist/models/index.d.ts +2 -0
  633. package/dist/models/nodeSource.d.ts +9 -0
  634. package/dist/particles/emission.d.ts +24 -0
  635. package/dist/particles/eyes.d.ts +24 -0
  636. package/dist/particles/glsl.d.ts +14 -0
  637. package/dist/particles/index.d.ts +10 -0
  638. package/dist/particles/motion.d.ts +42 -0
  639. package/dist/particles/presets.d.ts +12 -0
  640. package/dist/particles/ring.d.ts +58 -0
  641. package/dist/particles/selfTest.d.ts +53 -0
  642. package/dist/particles/settings.d.ts +127 -0
  643. package/dist/particles/shapes.d.ts +29 -0
  644. package/dist/particles/spawner.d.ts +71 -0
  645. package/dist/particles/system.d.ts +66 -0
  646. package/dist/particles.cjs +122 -0
  647. package/dist/particles.js +999 -0
  648. package/dist/product/ProductDimensions.d.ts +16 -0
  649. package/dist/product/ProductHotspot.d.ts +16 -0
  650. package/dist/product/ProductViewer.d.ts +9 -0
  651. package/dist/product/details.d.ts +53 -0
  652. package/dist/product/index.d.ts +14 -0
  653. package/dist/product/loadModelViewer.d.ts +4 -0
  654. package/dist/product/types.d.ts +71 -0
  655. package/dist/product/useProductAr.d.ts +37 -0
  656. package/dist/product/useProductDetails.d.ts +60 -0
  657. package/dist/product.cjs +1 -0
  658. package/dist/product.js +414 -0
  659. package/dist/providers-CEZQgz2s.cjs +62 -0
  660. package/dist/providers-CRuaD8bi.js +424 -0
  661. package/dist/quality/XRQualityController.d.ts +25 -0
  662. package/dist/quality/controller.d.ts +33 -0
  663. package/dist/quality/index.d.ts +6 -0
  664. package/dist/quality/types.d.ts +100 -0
  665. package/dist/quality/useXRQuality.d.ts +28 -0
  666. package/dist/render/layerStack.d.ts +29 -0
  667. package/dist/render/renderGroups.d.ts +47 -0
  668. package/dist/render/renderPasses.d.ts +26 -0
  669. package/dist/render/sceneBeforeRender.d.ts +12 -0
  670. package/dist/renderGroups-BADrepA1.cjs +1 -0
  671. package/dist/renderGroups-CNB99dZ2.js +152 -0
  672. package/dist/renderPasses-DgxUKn9b.cjs +158 -0
  673. package/dist/renderPasses-DuapJA6V.js +1290 -0
  674. package/dist/renderState-CJNmj5jz.js +39 -0
  675. package/dist/renderState-apSfg4eR.cjs +1 -0
  676. package/dist/scene-object/index.d.ts +146 -0
  677. package/dist/scene-object/runtimeRegistry.d.ts +14 -0
  678. package/dist/scene-object.cjs +1 -0
  679. package/dist/scene-object.js +40 -0
  680. package/dist/screen-image/screenImagePresets.d.ts +13 -0
  681. package/dist/screen-image/screenImageSettings.d.ts +57 -0
  682. package/dist/screen-text/screenTextPresets.d.ts +6 -0
  683. package/dist/screen-text/screenTextSettings.d.ts +147 -0
  684. package/dist/screen2d/coordinates.d.ts +107 -0
  685. package/dist/screen2d/index.d.ts +7 -0
  686. package/dist/screen2d/material-runtime.d.ts +32 -0
  687. package/dist/screen2d/screenTransform.d.ts +60 -0
  688. package/dist/screen2d/smoothing.d.ts +5 -0
  689. package/dist/screen2d/texture.d.ts +10 -0
  690. package/dist/screen2d/transform.d.ts +25 -0
  691. package/dist/screen2d/types.d.ts +90 -0
  692. package/dist/segmentation-BOZJdWFC.js +1911 -0
  693. package/dist/segmentation-J8GoNBvP.cjs +1 -0
  694. package/dist/segmentation2d/faceMemory.d.ts +28 -0
  695. package/dist/segmentation2d/faceRegions.d.ts +24 -0
  696. package/dist/segmentation2d/index.d.ts +9 -0
  697. package/dist/segmentation2d/maskUv.d.ts +23 -0
  698. package/dist/segmentation2d/rasterize.d.ts +14 -0
  699. package/dist/segmentation2d/types.d.ts +52 -0
  700. package/dist/selectors-BvJepq6H.js +196 -0
  701. package/dist/selectors-QB2qsaxy.cjs +1 -0
  702. package/dist/services/MetricsCollector/index.d.ts +7 -1
  703. package/dist/services/MetricsCollector/utils.d.ts +1 -1
  704. package/dist/session-BVX859as.cjs +31 -0
  705. package/dist/session-Cz8aie4K.js +493 -0
  706. package/dist/settings-BJ7FMBsO.js +111 -0
  707. package/dist/settings-C63FMBlF.cjs +1 -0
  708. package/dist/similarityFit-BFqHND2e.cjs +1 -0
  709. package/dist/similarityFit-Bbz-R8AY.js +91 -0
  710. package/dist/spring/index.d.ts +2 -0
  711. package/dist/spring/spring.d.ts +69 -0
  712. package/dist/spring/swing.d.ts +54 -0
  713. package/dist/subjects/index.d.ts +2 -0
  714. package/dist/subjects/select.d.ts +70 -0
  715. package/dist/subjects/types.d.ts +59 -0
  716. package/dist/texture/animatedTexture.d.ts +63 -0
  717. package/dist/texture/animationMath.d.ts +8 -0
  718. package/dist/texture/gifReader.d.ts +17 -0
  719. package/dist/texture/gifTextureSource.d.ts +16 -0
  720. package/dist/texture/sourceResolver.d.ts +30 -0
  721. package/dist/textures-BVwo9Z7z.js +38 -0
  722. package/dist/textures-DAfc61zz.cjs +1 -0
  723. package/dist/tracking/coordinates.d.ts +5 -0
  724. package/dist/tracking-config/apply.d.ts +57 -0
  725. package/dist/tracking-config/index.d.ts +7 -0
  726. package/dist/tracking-config/resolve.d.ts +25 -0
  727. package/dist/tracking-config/storage.d.ts +8 -0
  728. package/dist/tracking-config/types.d.ts +106 -0
  729. package/dist/tracking-config/useXRTrackingConfig.d.ts +38 -0
  730. package/dist/tracking.cjs +10 -1
  731. package/dist/tracking.js +1531 -294
  732. package/dist/trigger-D9L4GPmQ.js +3726 -0
  733. package/dist/trigger-DZ9vU7jo.cjs +147 -0
  734. package/dist/types/common.d.ts +11 -1
  735. package/dist/types/compositor.d.ts +21 -0
  736. package/dist/types/face.d.ts +21 -14
  737. package/dist/types/gesture-tracking.d.ts +2 -2
  738. package/dist/types/hand-tracking.d.ts +19 -2
  739. package/dist/types/holistic.d.ts +121 -0
  740. package/dist/types/index.d.ts +1 -1
  741. package/dist/types/model.d.ts +22 -2
  742. package/dist/types/nodes.d.ts +83 -6
  743. package/dist/types/segmentation.d.ts +26 -0
  744. package/dist/types/session.d.ts +50 -4
  745. package/dist/types/tracking.d.ts +8 -2
  746. package/dist/types/util-types.d.ts +1 -1
  747. package/dist/useBodies-BYzJpQ4L.js +75 -0
  748. package/dist/useBodies-Cxpmx6Bb.cjs +1 -0
  749. package/dist/useFaceInfo-BzEUj2OI.js +75 -0
  750. package/dist/useFaceInfo-DlLRAVNw.cjs +1 -0
  751. package/dist/useFaceResultReader-Cc4Qrutf.js +61 -0
  752. package/dist/useFaceResultReader-D3jOQNKz.cjs +1 -0
  753. package/dist/useInstructionHold-DOu-RpCM.js +53 -0
  754. package/dist/useInstructionHold-DwJY1Alr.cjs +1 -0
  755. package/dist/useIrisTracking-Bz4uLDa7.js +6190 -0
  756. package/dist/useIrisTracking-DRGWgoNy.cjs +35 -0
  757. package/dist/useLandmarkPoseFit-Bg-h9BPb.cjs +1 -0
  758. package/dist/useLandmarkPoseFit-Bmb3h6Mw.js +87 -0
  759. package/dist/useXRCapabilities-B1KLckqw.js +30 -0
  760. package/dist/useXRCapabilities-CZlPUBjF.cjs +1 -0
  761. package/dist/utils/canonicalRigidLandmarks.d.ts +8 -0
  762. package/dist/utils/drawNormalizedCrop.d.ts +22 -0
  763. package/dist/utils/fns.d.ts +6 -3
  764. package/dist/utils/headOccluderFit.d.ts +42 -0
  765. package/dist/utils/integrity.d.ts +25 -26
  766. package/dist/utils/landmarkBounds.d.ts +1 -1
  767. package/dist/utils/logger.d.ts +2 -2
  768. package/dist/utils/resolveNumFaces.d.ts +13 -0
  769. package/dist/utils/shoulderOccluderFit.d.ts +38 -0
  770. package/dist/utils/similarityFit.d.ts +23 -0
  771. package/dist/utils/updateThrottle.d.ts +2 -0
  772. package/dist/utils/useStableUniforms.d.ts +18 -0
  773. package/dist/utils/visionWasm.d.ts +18 -0
  774. package/dist/uv-BMFt19bg.cjs +1 -0
  775. package/dist/{index-BD-JWMjE.js → uv-DJU_XfmN.js} +15 -180
  776. package/dist/x-Co8jPhP0.js +127 -0
  777. package/dist/x-KC8E4Gaj.cjs +41 -0
  778. package/docs/MIGRATION_GUIDE.md +589 -0
  779. package/docs/SDK_DOCUMENTATION.md +1157 -0
  780. package/docs/api/adaptive-quality.mdx +104 -0
  781. package/docs/api/asset-lifecycle.mdx +78 -0
  782. package/docs/api/audio.mdx +36 -0
  783. package/docs/api/behavior-components.mdx +164 -0
  784. package/docs/api/body-instructions.mdx +287 -0
  785. package/docs/api/body-rig.mdx +384 -0
  786. package/docs/api/body-triggers.mdx +235 -0
  787. package/docs/api/camera-permission.mdx +142 -0
  788. package/docs/api/capture-recording.mdx +111 -0
  789. package/docs/api/coordinate-spaces.mdx +168 -0
  790. package/docs/api/cross-camera.mdx +89 -0
  791. package/docs/api/debug-ui-scene-editor.mdx +270 -0
  792. package/docs/api/diagnostics-calibration.mdx +97 -0
  793. package/docs/api/external-face-mesh.mdx +231 -0
  794. package/docs/api/face-actions.mdx +108 -0
  795. package/docs/api/face-attribute-expression.mdx +87 -0
  796. package/docs/api/face-binding-anchors.mdx +55 -0
  797. package/docs/api/face-character.mdx +157 -0
  798. package/docs/api/face-effects.mdx +28 -0
  799. package/docs/api/face-expression-controller.mdx +153 -0
  800. package/docs/api/face-info.mdx +118 -0
  801. package/docs/api/face-inset.mdx +204 -0
  802. package/docs/api/face-instructions.mdx +183 -0
  803. package/docs/api/face-liquify.mdx +196 -0
  804. package/docs/api/face-mesh.mdx +130 -0
  805. package/docs/api/face-morph.mdx +117 -0
  806. package/docs/api/face-painting.mdx +40 -0
  807. package/docs/api/face-reprojection.mdx +154 -0
  808. package/docs/api/face-retouching.mdx +81 -0
  809. package/docs/api/face-swap.mdx +350 -0
  810. package/docs/api/face-warp-3d.mdx +166 -0
  811. package/docs/api/faceless.mdx +143 -0
  812. package/docs/api/gestures.mdx +210 -0
  813. package/docs/api/hair.mdx +97 -0
  814. package/docs/api/hand-instructions.mdx +222 -0
  815. package/docs/api/hand-rig.mdx +661 -0
  816. package/docs/api/hand-touch.mdx +162 -0
  817. package/docs/api/head-occluder.mdx +563 -0
  818. package/docs/api/holistic-tracker.mdx +164 -0
  819. package/docs/api/instructions.mdx +323 -0
  820. package/docs/api/iris-tracking.mdx +247 -0
  821. package/docs/api/made-up-camera.mdx +131 -0
  822. package/docs/api/makeup-skin-tone.mdx +135 -0
  823. package/docs/api/makeup.mdx +353 -0
  824. package/docs/api/material-render-state.mdx +132 -0
  825. package/docs/api/multi-subject.mdx +185 -0
  826. package/docs/api/particles.mdx +183 -0
  827. package/docs/api/person-cutout.mdx +171 -0
  828. package/docs/api/pin-to-face-mesh.mdx +274 -0
  829. package/docs/api/product-ar.mdx +114 -0
  830. package/docs/api/product-details.mdx +78 -0
  831. package/docs/api/runtime-3d.mdx +316 -0
  832. package/docs/api/scene-object-store.mdx +213 -0
  833. package/docs/api/screen-image.mdx +67 -0
  834. package/docs/api/screen-shape.mdx +64 -0
  835. package/docs/api/screen-space-coordinates.mdx +75 -0
  836. package/docs/api/screen-text.mdx +39 -0
  837. package/docs/api/segmentation-overlay.mdx +301 -0
  838. package/docs/api/session-lifecycle.mdx +136 -0
  839. package/docs/api/texture-sources.mdx +74 -0
  840. package/docs/api/trackers.mdx +65 -0
  841. package/docs/api/tracking-config.mdx +108 -0
  842. package/docs/docs.json +121 -0
  843. package/docs/examples/lip-shaders.mdx +273 -0
  844. package/docs/examples/scene-object-recipes.mdx +194 -0
  845. package/docs/guides/face-atlas-template.svg +1 -0
  846. package/docs/guides/face-atlas-textures.mdx +186 -0
  847. package/docs/guides/face-texture-template.svg +1 -0
  848. package/docs/guides/harness-debug-ui.mdx +139 -0
  849. package/docs/guides/lip-effect-textures.mdx +368 -0
  850. package/docs/guides/lip-uv-template.png +0 -0
  851. package/docs/guides/lip-uv-template.svg +1 -0
  852. package/docs/guides/makeup-design-textures.mdx +109 -0
  853. package/docs/inspector/hierarchy-panel.mdx +51 -0
  854. package/docs/inspector/object-inspector-panel.mdx +51 -0
  855. package/docs/introduction.mdx +120 -0
  856. package/docs/scene-objects/overview.mdx +127 -0
  857. package/docs/scene-objects/render-groups.mdx +77 -0
  858. package/docs/scene-objects/runtime-rendering.mdx +75 -0
  859. package/docs/texture-api-consumer.md +84 -0
  860. package/package.json +86 -8
  861. package/settings.json +1998 -0
  862. package/dist/DebuggerUI-CEfdddkZ.cjs +0 -1
  863. package/dist/DebuggerUI-Dgop6Q6o.js +0 -269
  864. package/dist/components/FaceRetouch/retouchRegions.d.ts +0 -23
  865. package/dist/components/FaceRetouch/useFaceRetouchRegions.d.ts +0 -12
  866. package/dist/index-B5J4gzn2.cjs +0 -1
  867. package/dist/index-BVBVg96G.cjs +0 -1
  868. package/dist/index-CYMj26Ej.js +0 -1331
  869. package/dist/index-DtwHElmG.js +0 -157
  870. package/dist/index-PtFmD6B8.cjs +0 -1
  871. package/dist/internal-DH5d1Xnq.cjs +0 -1
  872. package/dist/modules/XRClient/index.d.ts +0 -9
  873. package/dist/modules/index.d.ts +0 -1
  874. package/dist/selectors-BHO6TnoC.js +0 -59
  875. package/dist/selectors-Bub0o3qy.cjs +0 -1
  876. package/dist/services/ApiService.d.ts +0 -12
  877. package/dist/types/client.d.ts +0 -3
  878. package/dist/useFaceResults-cpsSmKKc.js +0 -81
  879. package/dist/useFaceResults-hVUJYSEY.cjs +0 -1
@@ -0,0 +1,3740 @@
1
+ var As = Object.defineProperty;
2
+ var Is = (e, s, t) => s in e ? As(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
3
+ var u = (e, s, t) => Is(e, typeof s != "symbol" ? s + "" : s, t);
4
+ import { jsxs as Fs, jsx as yt } from "react/jsx-runtime";
5
+ import { useRef as he, useMemo as xe, useEffect as ye, useContext as Je, useCallback as wt, createElement as Ps, createContext as _t, useState as _s } from "react";
6
+ import { FilesetResolver as $, PoseLandmarker as Ds, FaceLandmarker as Os, GestureRecognizer as Ls, HolisticLandmarker as Ns, HandLandmarker as Bs, ImageSegmenter as Dt, DrawingUtils as Hs } from "@mediapipe/tasks-vision";
7
+ import * as z from "three";
8
+ import { Vector2 as Us, Raycaster as zs, Ray as Ws, Vector3 as qs, RGBAFormat as Ot, LinearFilter as Re, CanvasTexture as Lt, SRGBColorSpace as Vs } from "three";
9
+ const W = {
10
+ // Pinned to the CDN, NOT build-env-driven: a stale VITE_ASSET_STORAGE_ENDPOINT
11
+ // baked a now-deleted CloudFront domain into every published bundle, breaking
12
+ // WASM/model loads at runtime. The host must never come from a mutable env value.
13
+ assetStorageEndpoint: "https://cdn.vincentt.studio",
14
+ // Versioned bucket for SDK-shipped reference assets (canonical face model, face textures, etc.).
15
+ sdkAssetsBaseUrl: "https://cdn.vincentt.studio/assets/sdk/face/v1",
16
+ // Debug-ui sample media (the preview presets: clips and stills). Overridable
17
+ // at app start — the playground points it at a local folder while new clips
18
+ // are reviewed before they are published to the CDN.
19
+ debugMediaBaseUrl: "https://cdn.vincentt.studio/assets/sdk/debug-ui/v1",
20
+ loggerPrefix: "[vincentt-xr]:",
21
+ sessionCheckInterval: 3e4
22
+ };
23
+ var P = /* @__PURE__ */ ((e) => (e.WEBCAM = "webcam", e.STREAM = "stream", e.CANVAS = "canvas", e))(P || {}), F = /* @__PURE__ */ ((e) => (e.HAND_TRACKER = "vincentt.xr.hand-tracker", e.GESTURE_TRACKER = "vincentt.xr.gesture-tracker", e.FACE_TRACKER = "vincentt.xr.face-tracker", e.BODY_TRACKER = "vincentt.xr.body-tracker", e.HOLISTIC_TRACKER = "vincentt.xr.holistic-tracker", e.BACKGROUND_SEGMENTATION = "vincentt.xr.background-segmentation", e.SEMANTIC_SEGMENTATION = "vincentt.xr.semantic-segmentation", e))(F || {});
24
+ const He = (e) => Array.from({ length: e }, () => ({ x: 0, y: 0, z: 0 }));
25
+ class Ks {
26
+ constructor(s) {
27
+ u(this, "slots", []);
28
+ this.options = s;
29
+ }
30
+ setOptions(s) {
31
+ this.options = s;
32
+ }
33
+ /** Landmark sets to draw this frame: live faces, plus held/predicted ones. */
34
+ update(s, t) {
35
+ const { holdMs: n, predictMs: i, maxVelocityGapMs: r = 250 } = this.options, o = [], a = Math.max(s.length, this.slots.length);
36
+ for (let d = 0; d < a; d += 1) {
37
+ const l = s[d], h = this.slots[d] ?? null;
38
+ if (l && l.length > 0) {
39
+ const M = h && h.points.length === l.length ? h : null, x = M ?? {
40
+ points: He(l.length),
41
+ velocity: He(l.length),
42
+ lastSeen: t,
43
+ output: He(l.length)
44
+ }, b = (t - x.lastSeen) / 1e3, T = M !== null && b > 0 && b * 1e3 <= r;
45
+ for (let R = 0; R < l.length; R += 1) {
46
+ const y = l[R], g = x.points[R], p = x.velocity[R], v = y.z ?? 0;
47
+ T ? (p.x = 0.5 * p.x + 0.5 * ((y.x - g.x) / b), p.y = 0.5 * p.y + 0.5 * ((y.y - g.y) / b), p.z = 0.5 * p.z + 0.5 * ((v - g.z) / b)) : (p.x = 0, p.y = 0, p.z = 0), g.x = y.x, g.y = y.y, g.z = v;
48
+ }
49
+ x.lastSeen = t, this.slots[d] = x, o.push(l);
50
+ continue;
51
+ }
52
+ if (!h) continue;
53
+ const m = t - h.lastSeen;
54
+ if (m > n) {
55
+ this.slots[d] = null;
56
+ continue;
57
+ }
58
+ const w = Math.max(0, Math.min(m, i)) / 1e3;
59
+ for (let M = 0; M < h.points.length; M += 1)
60
+ h.output[M].x = h.points[M].x + h.velocity[M].x * w, h.output[M].y = h.points[M].y + h.velocity[M].y * w, h.output[M].z = h.points[M].z + h.velocity[M].z * w;
61
+ o.push(h.output);
62
+ }
63
+ for (; this.slots.length > 0 && this.slots[this.slots.length - 1] === null; ) this.slots.pop();
64
+ return o;
65
+ }
66
+ reset() {
67
+ this.slots = [];
68
+ }
69
+ }
70
+ const ue = (e, s = { x: 0, y: 0, z: 0 }) => (s.x = e.x * 2 - 1, s.y = 1 - e.y * 2, s.z = -e.z, s), Gs = (e, s = { x: 0, y: 0, z: 0 }) => (s.x = (e.x + 1) / 2, s.y = (1 - e.y) / 2, s.z = -e.z, s), Nt = "https://storage.googleapis.com/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task", Xs = 250, Ys = 0, js = 768, je = (e) => ({
71
+ hands: (e == null ? void 0 : e.hands) ?? "both",
72
+ analysisMaxDimension: (e == null ? void 0 : e.analysisMaxDimension) ?? js,
73
+ holdMs: (e == null ? void 0 : e.holdMs) ?? Xs,
74
+ predictMs: (e == null ? void 0 : e.predictMs) ?? Ys
75
+ }), Qs = () => ({
76
+ version: 0,
77
+ timestampMs: 0,
78
+ face: null,
79
+ leftHand: null,
80
+ rightHand: null,
81
+ pose: null
82
+ }), vt = [
83
+ 0,
84
+ 4,
85
+ 5,
86
+ 6,
87
+ 1,
88
+ 2,
89
+ 3,
90
+ 8,
91
+ 7,
92
+ 10,
93
+ 9,
94
+ 12,
95
+ 11,
96
+ 14,
97
+ 13,
98
+ 16,
99
+ 15,
100
+ 18,
101
+ 17,
102
+ 20,
103
+ 19,
104
+ 22,
105
+ 21,
106
+ 24,
107
+ 23,
108
+ 26,
109
+ 25,
110
+ 28,
111
+ 27,
112
+ 30,
113
+ 29,
114
+ 32,
115
+ 31
116
+ ], xt = (e, s) => {
117
+ if (e.length !== vt.length) return e;
118
+ s.length = e.length;
119
+ for (let t = 0; t < e.length; t += 1) s[t] = e[vt[t]];
120
+ return s;
121
+ };
122
+ class ke {
123
+ constructor(s, t) {
124
+ u(this, "memory");
125
+ u(this, "holdMs");
126
+ u(this, "lastLiveMs", -1 / 0);
127
+ u(this, "lastConfidence", 0);
128
+ this.holdMs = s, this.memory = new Ks({ holdMs: s, predictMs: t });
129
+ }
130
+ setOptions(s, t) {
131
+ this.holdMs = s, this.memory.setOptions({ holdMs: s, predictMs: t });
132
+ }
133
+ reset() {
134
+ this.memory.reset(), this.lastLiveMs = -1 / 0, this.lastConfidence = 0;
135
+ }
136
+ /**
137
+ * Returns the landmarks to publish this frame (live, or replayed from
138
+ * memory), or `undefined` when the stream is neither detected nor held.
139
+ * A held stream's confidence decays linearly from the last live value to
140
+ * 0 at `holdMs`.
141
+ */
142
+ bridge(s, t, n) {
143
+ const i = s !== void 0 && s.length > 0, r = this.memory.update(i ? [s] : [], n)[0];
144
+ if (!r) return;
145
+ if (i)
146
+ return this.lastLiveMs = n, this.lastConfidence = t, { points: r, held: !1, confidence: t };
147
+ const o = n - this.lastLiveMs, a = this.holdMs > 0 ? Math.max(0, 1 - o / this.holdMs) : 0;
148
+ return { points: r, held: !0, confidence: this.lastConfidence * a };
149
+ }
150
+ }
151
+ const ce = (e, s, t) => {
152
+ for (e.length > s && (e.length = s); e.length < s; ) e.push(t());
153
+ return e;
154
+ }, Ue = (e, s) => {
155
+ e.x = s.x, e.y = s.y, e.z = s.z;
156
+ }, Js = (e) => {
157
+ if (e.length === 0) return 0;
158
+ let s = 0;
159
+ for (let t = 0; t < e.length; t += 1) s += e[t].visibility ?? 0;
160
+ return s / e.length;
161
+ };
162
+ class Zs {
163
+ constructor(s) {
164
+ u(this, "options", je());
165
+ u(this, "faceMemory", new ke(this.options.holdMs, this.options.predictMs));
166
+ u(this, "leftHandMemory", new ke(this.options.holdMs, this.options.predictMs));
167
+ u(this, "rightHandMemory", new ke(this.options.holdMs, this.options.predictMs));
168
+ u(this, "poseMemory", new ke(this.options.holdMs, this.options.predictMs));
169
+ u(this, "face", {
170
+ landmarks: [],
171
+ blendshapes: {},
172
+ confidence: 0,
173
+ held: !1
174
+ });
175
+ u(this, "leftHand", {
176
+ handedness: "left",
177
+ landmarks: [],
178
+ worldLandmarks: [],
179
+ confidence: 0,
180
+ held: !1
181
+ });
182
+ u(this, "rightHand", {
183
+ handedness: "right",
184
+ landmarks: [],
185
+ worldLandmarks: [],
186
+ confidence: 0,
187
+ held: !1
188
+ });
189
+ u(this, "poseScratch", []);
190
+ u(this, "poseWorldScratch", []);
191
+ u(this, "pose", {
192
+ landmarks: [],
193
+ worldLandmarks: [],
194
+ visibility: [],
195
+ confidence: 0,
196
+ held: !1
197
+ });
198
+ this.setOptions(s);
199
+ }
200
+ getOptions() {
201
+ return this.options;
202
+ }
203
+ setOptions(s) {
204
+ this.options = je({ ...this.options, ...s });
205
+ const { holdMs: t, predictMs: n } = this.options;
206
+ for (const i of this.memories()) i.setOptions(t, n);
207
+ }
208
+ reset() {
209
+ for (const s of this.memories()) s.reset();
210
+ }
211
+ memories() {
212
+ return [this.faceMemory, this.leftHandMemory, this.rightHandMemory, this.poseMemory];
213
+ }
214
+ /**
215
+ * Publish `raw` (or a miss when `undefined`) into `result` at `nowMs`.
216
+ *
217
+ * `mirrored` says the analysed frame is a mirror of the person (the
218
+ * session's webcam feed). Pose left/right follow the image, and holistic
219
+ * assigns hands from the pose, so on a mirrored frame MediaPipe's "left"
220
+ * is the person's right. Swap both the hands and the pose's left/right
221
+ * landmarks so the whole result is anatomical and self-consistent
222
+ * (`leftHand` and pose wrist 15 are the same physical hand), matching the
223
+ * convention `HandTracker` reports on that feed.
224
+ */
225
+ update(s, t, n, i = !1) {
226
+ var l, h, m, w;
227
+ n.face = this.updateFace(s, t);
228
+ const r = {
229
+ landmarks: (l = s == null ? void 0 : s.leftHandLandmarks) == null ? void 0 : l[0],
230
+ world: (h = s == null ? void 0 : s.leftHandWorldLandmarks) == null ? void 0 : h[0]
231
+ }, o = {
232
+ landmarks: (m = s == null ? void 0 : s.rightHandLandmarks) == null ? void 0 : m[0],
233
+ world: (w = s == null ? void 0 : s.rightHandWorldLandmarks) == null ? void 0 : w[0]
234
+ }, a = i ? o : r, d = i ? r : o;
235
+ return n.leftHand = this.updateHand("left", a.landmarks, a.world, t), n.rightHand = this.updateHand("right", d.landmarks, d.world, t), n.pose = this.updatePose(s, t, i), n.timestampMs = t, n.version += 1, n;
236
+ }
237
+ updateFace(s, t) {
238
+ var a, d, l, h;
239
+ const n = (a = s == null ? void 0 : s.faceLandmarks) == null ? void 0 : a[0], i = this.faceMemory.bridge(n, 1, t);
240
+ if (!i) return null;
241
+ const { face: r } = this, o = !i.held && n;
242
+ ce(r.landmarks, i.points.length, () => ({
243
+ x: 0,
244
+ y: 0,
245
+ z: 0,
246
+ visibility: 0
247
+ }));
248
+ for (let m = 0; m < i.points.length; m += 1) {
249
+ const w = r.landmarks[m];
250
+ Ue(w, i.points[m]), w.visibility = o ? ((d = n[m]) == null ? void 0 : d.visibility) ?? 0 : 0;
251
+ }
252
+ if (o) {
253
+ const m = (h = (l = s == null ? void 0 : s.faceBlendshapes) == null ? void 0 : l[0]) == null ? void 0 : h.categories;
254
+ if (m)
255
+ for (const w of m) r.blendshapes[w.categoryName] = w.score;
256
+ }
257
+ return r.confidence = i.confidence, r.held = i.held, r;
258
+ }
259
+ updateHand(s, t, n, i) {
260
+ const r = s === "left" ? this.leftHandMemory : this.rightHandMemory, { hands: o } = this.options;
261
+ if (o === "none" || o !== "both" && o !== s)
262
+ return r.reset(), null;
263
+ const a = r.bridge(t, 1, i);
264
+ if (!a) return null;
265
+ const d = s === "left" ? this.leftHand : this.rightHand;
266
+ ce(d.landmarks, a.points.length, () => ({ x: 0, y: 0, z: 0 }));
267
+ for (let l = 0; l < a.points.length; l += 1)
268
+ ue(a.points[l], d.landmarks[l]);
269
+ if (!a.held && n) {
270
+ ce(d.worldLandmarks, n.length, () => ({ x: 0, y: 0, z: 0 }));
271
+ for (let l = 0; l < n.length; l += 1) Ue(d.worldLandmarks[l], n[l]);
272
+ }
273
+ return d.confidence = a.confidence, d.held = a.held, d;
274
+ }
275
+ updatePose(s, t, n) {
276
+ var m, w, M;
277
+ const i = (m = s == null ? void 0 : s.poseLandmarks) == null ? void 0 : m[0], r = i && n ? xt(i, this.poseScratch) : i, o = this.poseMemory.bridge(r, r ? Js(r) : 0, t);
278
+ if (!o) return null;
279
+ const { pose: a } = this, d = !o.held && r;
280
+ ce(a.landmarks, o.points.length, () => ({ x: 0, y: 0, z: 0 })), ce(a.visibility, o.points.length, () => 0);
281
+ for (let x = 0; x < o.points.length; x += 1)
282
+ ue(o.points[x], a.landmarks[x]), d && (a.visibility[x] = ((w = r[x]) == null ? void 0 : w.visibility) ?? 0);
283
+ const l = (M = s == null ? void 0 : s.poseWorldLandmarks) == null ? void 0 : M[0], h = l && n ? xt(l, this.poseWorldScratch) : l;
284
+ if (d && h) {
285
+ ce(a.worldLandmarks, h.length, () => ({ x: 0, y: 0, z: 0 }));
286
+ for (let x = 0; x < h.length; x += 1) Ue(a.worldLandmarks[x], h[x]);
287
+ }
288
+ return a.confidence = o.confidence, a.held = o.held, a;
289
+ }
290
+ }
291
+ const Bt = {
292
+ "camera-permission-denied": "Camera access was blocked. Allow camera permissions in your browser, then refresh.",
293
+ "camera-in-use": "Camera is already in use by another app or browser tab. Close it and refresh.",
294
+ "no-camera": "No camera was found on this device.",
295
+ "camera-insecure-context": "Camera access needs HTTPS (or localhost). Open the page over HTTPS.",
296
+ "camera-unsupported": "This browser cannot open the camera.",
297
+ "camera-lost": "The camera stopped sending frames (disconnected, revoked, or taken by another app).",
298
+ "webgl-unavailable": "WebGL is unavailable, so nothing can render or track.",
299
+ "offscreen-canvas-unavailable": "OffscreenCanvas is unavailable; the tracker feed cannot be built.",
300
+ "wasm-unavailable": "WebAssembly is unavailable; the tracking engine cannot load.",
301
+ "model-unreachable": "The tracker model could not be downloaded.",
302
+ "model-integrity": "The tracker model failed its integrity check.",
303
+ "model-init-failed": "The tracker failed to initialize on this device.",
304
+ "placement-unsupported": "This device cannot place 3D objects in the room (no WebXR, Scene Viewer or Quick Look).",
305
+ unknown: "Tracking is unavailable for an unknown reason."
306
+ }, $s = {
307
+ "camera-permission-denied": !0,
308
+ "camera-in-use": !0,
309
+ "no-camera": !1,
310
+ "camera-insecure-context": !1,
311
+ "camera-unsupported": !1,
312
+ "camera-lost": !0,
313
+ "webgl-unavailable": !1,
314
+ "offscreen-canvas-unavailable": !1,
315
+ "wasm-unavailable": !1,
316
+ "model-unreachable": !0,
317
+ "model-integrity": !1,
318
+ "model-init-failed": !1,
319
+ "placement-unsupported": !1,
320
+ unknown: !0
321
+ }, _ = (e, s = Bt[e]) => ({ code: e, message: s, recoverable: $s[e] }), en = {
322
+ [F.FACE_TRACKER]: "/assets/xr/models/face_tracking.task",
323
+ [F.HAND_TRACKER]: "/assets/xr/models/hand_tracking.task",
324
+ [F.GESTURE_TRACKER]: "/assets/xr/models/gesture_tracking.task",
325
+ [F.BODY_TRACKER]: "/assets/xr/models/body_tracking.task",
326
+ [F.BACKGROUND_SEGMENTATION]: "/assets/xr/models/segmentation.tflite",
327
+ [F.SEMANTIC_SEGMENTATION]: "/assets/xr/models/selfie_multiclass_256x256.tflite",
328
+ [F.HOLISTIC_TRACKER]: Nt
329
+ }, Ht = (e) => {
330
+ const s = en[e];
331
+ return s ? /^https?:/.test(s) ? s : new URL(s, W.assetStorageEndpoint).toString() : null;
332
+ }, tn = Object.values(F), sn = () => {
333
+ var t, n, i;
334
+ const e = typeof window < "u", s = typeof document < "u";
335
+ return {
336
+ navigator: typeof navigator < "u" ? navigator : void 0,
337
+ isSecureContext: e ? window.isSecureContext : void 0,
338
+ createCanvas: s ? () => document.createElement("canvas") : void 0,
339
+ offscreenCanvas: typeof OffscreenCanvas < "u",
340
+ wasm: typeof WebAssembly < "u",
341
+ fetch: typeof fetch < "u" ? fetch.bind(globalThis) : void 0,
342
+ now: () => typeof performance < "u" ? performance.now() : Date.now(),
343
+ xrSessionSupported: typeof navigator < "u" && ((t = navigator.xr) != null && t.isSessionSupported) ? (r) => navigator.xr.isSessionSupported(r).catch(() => !1) : void 0,
344
+ relSupportsAr: s ? ((i = (n = document.createElement("a").relList) == null ? void 0 : n.supports) == null ? void 0 : i.call(n, "ar")) === !0 : void 0,
345
+ userAgent: typeof navigator < "u" ? navigator.userAgent : void 0
346
+ };
347
+ }, nn = (e) => !!e && /Android/.test(e) && /(Chrome|SamsungBrowser)\//.test(e) && !/Firefox|OPR\//.test(e), rn = async (e) => {
348
+ let s = !1;
349
+ if (e.xrSessionSupported)
350
+ try {
351
+ s = await e.xrSessionSupported("immersive-ar");
352
+ } catch {
353
+ s = !1;
354
+ }
355
+ const t = nn(e.userAgent), n = e.relSupportsAr === !0, i = s || t || n;
356
+ return {
357
+ webxr: s,
358
+ sceneViewer: t,
359
+ quickLook: n,
360
+ any: i,
361
+ reason: i ? null : _("placement-unsupported")
362
+ };
363
+ }, an = (e) => {
364
+ switch (e) {
365
+ case "granted":
366
+ return "supported";
367
+ case "denied":
368
+ return "permission-denied";
369
+ case "prompt":
370
+ return "permission-prompt";
371
+ default:
372
+ return "unknown";
373
+ }
374
+ }, on = async (e, s) => {
375
+ var a, d, l;
376
+ const t = e.isSecureContext ?? !0, n = (a = e.navigator) == null ? void 0 : a.mediaDevices;
377
+ if (!t)
378
+ return {
379
+ status: "unsupported",
380
+ reason: _("camera-insecure-context"),
381
+ deviceCount: null,
382
+ secureContext: t
383
+ };
384
+ if (!n || typeof n.getUserMedia != "function")
385
+ return {
386
+ status: "unsupported",
387
+ reason: _("camera-unsupported"),
388
+ deviceCount: null,
389
+ secureContext: t
390
+ };
391
+ let i = "unknown";
392
+ if (s && ((l = (d = e.navigator) == null ? void 0 : d.permissions) != null && l.query))
393
+ try {
394
+ const h = await e.navigator.permissions.query({ name: "camera" });
395
+ i = an(h.state);
396
+ } catch {
397
+ i = "unknown";
398
+ }
399
+ let r = null, o = !1;
400
+ if (typeof n.enumerateDevices == "function")
401
+ try {
402
+ const h = await n.enumerateDevices();
403
+ r = h.filter((m) => m.kind === "videoinput").length, o = h.some((m) => !!m.label);
404
+ } catch {
405
+ r = null;
406
+ }
407
+ return i === "permission-denied" ? {
408
+ status: i,
409
+ reason: _("camera-permission-denied"),
410
+ deviceCount: r,
411
+ secureContext: t
412
+ } : r === 0 && (i === "supported" || o) ? {
413
+ status: "unsupported",
414
+ reason: _("no-camera"),
415
+ deviceCount: r,
416
+ secureContext: t
417
+ } : { status: i, reason: null, deviceCount: r, secureContext: t };
418
+ }, cn = (e) => {
419
+ var t;
420
+ const s = (t = e.createCanvas) == null ? void 0 : t.call(e);
421
+ if (!s) return 0;
422
+ try {
423
+ if (s.getContext("webgl2")) return 2;
424
+ if (s.getContext("webgl") || s.getContext("experimental-webgl")) return 1;
425
+ } catch {
426
+ return 0;
427
+ }
428
+ return 0;
429
+ }, ln = (e) => {
430
+ var o;
431
+ const s = cn(e), t = e.offscreenCanvas ?? !1, n = e.wasm ?? !1, i = !!((o = e.navigator) != null && o.gpu);
432
+ let r = null;
433
+ return s === 0 ? r = _("webgl-unavailable") : t ? n || (r = _("wasm-unavailable")) : r = _("offscreen-canvas-unavailable"), {
434
+ status: r ? "unsupported" : "supported",
435
+ reason: r,
436
+ webglVersion: s,
437
+ webgpu: i,
438
+ offscreenCanvas: t,
439
+ wasm: n
440
+ };
441
+ }, dn = async (e, s, t) => {
442
+ var o, a;
443
+ const n = Ht(e);
444
+ if (!n || !s.fetch)
445
+ return { model: e, status: "unknown", reason: null, url: n, bytes: null };
446
+ const i = typeof AbortController < "u" ? new AbortController() : void 0, r = setTimeout(() => i == null ? void 0 : i.abort(), t);
447
+ try {
448
+ const d = await s.fetch(n, { method: "HEAD", signal: i == null ? void 0 : i.signal });
449
+ if (!d.ok)
450
+ return {
451
+ model: e,
452
+ status: "unsupported",
453
+ reason: _(
454
+ "model-unreachable",
455
+ `${Bt["model-unreachable"]} (${d.status})`
456
+ ),
457
+ url: n,
458
+ bytes: null
459
+ };
460
+ const l = Number(((a = (o = d.headers) == null ? void 0 : o.get) == null ? void 0 : a.call(o, "content-length")) ?? NaN);
461
+ return {
462
+ model: e,
463
+ status: "supported",
464
+ reason: null,
465
+ url: n,
466
+ bytes: Number.isFinite(l) && l > 0 ? l : null
467
+ };
468
+ } catch {
469
+ return {
470
+ model: e,
471
+ status: "unsupported",
472
+ reason: _("model-unreachable"),
473
+ url: n,
474
+ bytes: null
475
+ };
476
+ } finally {
477
+ clearTimeout(r);
478
+ }
479
+ }, ir = async (e = {}, s = sn()) => {
480
+ const t = e.timeoutMs ?? 4e3, n = new Set(e.models ?? []), [i, r, o] = await Promise.all([
481
+ on(s, e.queryPermission ?? !0),
482
+ Promise.all(
483
+ tn.map(
484
+ async (l) => n.has(l) ? dn(l, s, t) : {
485
+ model: l,
486
+ status: "unknown",
487
+ reason: null,
488
+ url: Ht(l),
489
+ bytes: null
490
+ }
491
+ )
492
+ ),
493
+ rn(s)
494
+ ]), a = ln(s), d = Object.fromEntries(r.map((l) => [l.model, l]));
495
+ return {
496
+ camera: i,
497
+ rendering: a,
498
+ placement: o,
499
+ models: d,
500
+ canRunTracking: a.status === "supported" && i.status !== "unsupported",
501
+ checkedAt: s.now ? s.now() : Date.now()
502
+ };
503
+ }, Ut = (e) => {
504
+ switch (e) {
505
+ case "permission-denied":
506
+ return _("camera-permission-denied");
507
+ case "camera-in-use":
508
+ return _("camera-in-use");
509
+ case "no-camera":
510
+ return _("no-camera");
511
+ case "camera-lost":
512
+ return _("camera-lost");
513
+ case "unsupported":
514
+ return _("camera-unsupported");
515
+ default:
516
+ return _("unknown");
517
+ }
518
+ }, rr = (e, s) => {
519
+ const { camera: t, rendering: n } = e, i = e.models[s], r = t.status === "permission-prompt" || t.status === "unknown";
520
+ return n.reason ? { supported: !1, reason: n.reason, needsPermission: r } : t.reason ? { supported: !1, reason: t.reason, needsPermission: r } : i != null && i.reason ? { supported: !1, reason: i.reason, needsPermission: r } : { supported: !0, reason: null, needsPermission: r };
521
+ }, ar = (e) => {
522
+ const s = e instanceof Error ? e.message : String(e ?? ""), t = s.toLowerCase();
523
+ return t.includes("integrity") || t.includes("sha-384") || t.includes("sha384") ? _("model-integrity", s) : t.includes("failed to fetch") || t.includes("networkerror") || t.includes("load failed") || /\b(404|403|5\d\d)\b/.test(t) || t.includes("fetch") ? _("model-unreachable", s) : t.includes("webgl") || t.includes("gpu") ? _("webgl-unavailable", s) : s ? _("model-init-failed", s) : _("unknown");
524
+ }, zt = (e) => {
525
+ switch (e instanceof DOMException ? e.name : "") {
526
+ case "NotAllowedError":
527
+ case "PermissionDeniedError":
528
+ return "permission-denied";
529
+ case "NotReadableError":
530
+ case "TrackStartError":
531
+ return "camera-in-use";
532
+ case "NotFoundError":
533
+ case "DevicesNotFoundError":
534
+ return "no-camera";
535
+ case "NotSupportedError":
536
+ case "SecurityError":
537
+ case "OverconstrainedError":
538
+ return "unsupported";
539
+ default:
540
+ return e instanceof TypeError ? "unsupported" : "unknown";
541
+ }
542
+ }, St = {
543
+ "permission-denied": "Camera access was blocked. Allow camera permissions in your browser, then refresh.",
544
+ "camera-in-use": "Camera is already in use by another app or browser tab. Close it and refresh.",
545
+ "no-camera": "No camera was found on this device.",
546
+ "camera-lost": "The camera stopped sending frames. Reconnect it or re-allow access, then start again.",
547
+ unsupported: "Unable to access camera. Allow camera permissions in your browser, then refresh.",
548
+ unknown: "Unable to access camera. Allow camera permissions in your browser, then refresh."
549
+ }, Ze = () => ({
550
+ mediaDevices: typeof navigator < "u" ? navigator.mediaDevices : void 0,
551
+ permissions: typeof navigator < "u" ? navigator.permissions : void 0,
552
+ isSecureContext: typeof window < "u" ? window.isSecureContext : void 0
553
+ }), Wt = async (e = Ze()) => {
554
+ var s;
555
+ if (!((s = e.permissions) != null && s.query)) return { state: "unknown", prompt: !1 };
556
+ try {
557
+ const t = await e.permissions.query({ name: "camera" });
558
+ return t.state === "granted" ? { state: "granted", prompt: !1 } : t.state === "denied" ? { state: "blocked", prompt: !1 } : { state: "unknown", prompt: t.state === "prompt" };
559
+ } catch {
560
+ return { state: "unknown", prompt: !1 };
561
+ }
562
+ }, qt = (e, s) => e === "permission-denied" ? {
563
+ state: s === "blocked" ? "blocked" : "denied",
564
+ reason: _("camera-permission-denied")
565
+ } : { state: "unavailable", reason: Ut(e) }, or = async (e = {}, s = Ze()) => {
566
+ var n;
567
+ if (s.isSecureContext === !1)
568
+ return {
569
+ state: "unavailable",
570
+ reason: _("camera-insecure-context"),
571
+ stream: null
572
+ };
573
+ const t = (n = s.mediaDevices) == null ? void 0 : n.getUserMedia;
574
+ if (typeof t != "function")
575
+ return {
576
+ state: "unavailable",
577
+ reason: _("camera-unsupported"),
578
+ stream: null
579
+ };
580
+ try {
581
+ const i = await t.call(
582
+ s.mediaDevices,
583
+ e.constraints ?? { video: { facingMode: "user" } }
584
+ );
585
+ return e.keepStream ? { state: "granted", reason: null, stream: i } : (i.getTracks().forEach((r) => r.stop()), { state: "granted", reason: null, stream: null });
586
+ } catch (i) {
587
+ const r = zt(i), o = await Wt(s);
588
+ return { ...qt(r, o.state), stream: null };
589
+ }
590
+ }, cr = async (e, s = Ze()) => {
591
+ var t, n;
592
+ if (!((t = s.permissions) != null && t.query)) return () => {
593
+ };
594
+ try {
595
+ const i = await s.permissions.query({ name: "camera" }), r = () => {
596
+ i.state === "granted" ? e({ state: "granted", prompt: !1 }) : i.state === "denied" ? e({ state: "blocked", prompt: !1 }) : e({ state: "unknown", prompt: i.state === "prompt" });
597
+ };
598
+ return (n = i.addEventListener) == null || n.call(i, "change", r), () => {
599
+ var o;
600
+ return (o = i.removeEventListener) == null ? void 0 : o.call(i, "change", r);
601
+ };
602
+ } catch {
603
+ return () => {
604
+ };
605
+ }
606
+ }, lr = (e) => e === "unknown" || e === "denied" || e === "granted", dr = {
607
+ unknown: "This experience uses your camera. Nothing is recorded or uploaded.",
608
+ requesting: "Waiting for you to allow the camera…",
609
+ granted: "Camera access granted.",
610
+ denied: "Camera access was not allowed. You can try again.",
611
+ blocked: "Camera access is blocked for this site. Allow it in your browser's site settings, then reload.",
612
+ unavailable: "The camera is unavailable on this device right now."
613
+ }, hn = (e, s, t = "cover", n = 1) => {
614
+ if (e.width <= 0 || e.height <= 0 || s.width <= 0 || s.height <= 0)
615
+ return null;
616
+ const i = Number.isFinite(n) && n > 0 ? n : 1, r = s.width / e.width, o = s.height / e.height, a = t === "contain" ? o <= r : o >= r, d = (a ? o : r) * i, l = a ? e.width * o * i : s.width * i, h = a ? s.height * i : e.height * r * i;
617
+ return {
618
+ scale: d,
619
+ drawWidth: l,
620
+ drawHeight: h,
621
+ offsetX: (s.width - l) / 2,
622
+ offsetY: (s.height - h) / 2
623
+ };
624
+ }, Se = (e) => e === "webcam" || e === void 0, un = ({
625
+ source: e,
626
+ feed: s,
627
+ zoom: t = 1,
628
+ mirrored: n = !1
629
+ }) => {
630
+ const i = hn(e, s, "cover", t);
631
+ return i ? { ...i, source: e, feed: s, zoom: Number.isFinite(t) && t > 0 ? t : 1, mirrored: n } : null;
632
+ }, hr = (e, s, t = { x: 0, y: 0 }) => {
633
+ const n = s.mirrored ? s.source.width - e.x : e.x;
634
+ return t.x = (s.offsetX + n * s.scale) / s.feed.width, t.y = (s.offsetY + e.y * s.scale) / s.feed.height, t;
635
+ }, mn = (e, s, t = { x: 0, y: 0 }) => {
636
+ const n = (e.x * s.feed.width - s.offsetX) / s.scale;
637
+ return t.x = s.mirrored ? s.source.width - n : n, t.y = (e.y * s.feed.height - s.offsetY) / s.scale, t;
638
+ }, ur = (e, s) => {
639
+ const t = mn(e, s);
640
+ return t.x >= 0 && t.x <= s.source.width && t.y >= 0 && t.y <= s.source.height;
641
+ }, mr = (e, s = { x: 0, y: 0 }) => (s.x = 1 - e.x, s.y = e.y, e.z !== void 0 && (s.z = e.z), s), fr = (e, s, t, n = { x: 0, y: 0 }) => {
642
+ switch (t) {
643
+ case 90:
644
+ return n.x = s.height - e.y, n.y = e.x, n;
645
+ case 180:
646
+ return n.x = s.width - e.x, n.y = s.height - e.y, n;
647
+ case 270:
648
+ return n.x = e.y, n.y = s.width - e.x, n;
649
+ default:
650
+ return n.x = e.x, n.y = e.y, n;
651
+ }
652
+ }, gr = (e, s) => s === 90 || s === 270 ? { width: e.height, height: e.width } : { width: e.width, height: e.height };
653
+ class N extends Error {
654
+ constructor(s) {
655
+ super(s), this.name = "VincenttXRError";
656
+ }
657
+ }
658
+ class fn {
659
+ constructor(s) {
660
+ u(this, "options");
661
+ const t = {
662
+ verbose: !1,
663
+ prefix: W.loggerPrefix
664
+ };
665
+ this.options = { ...t, ...s };
666
+ }
667
+ log(...s) {
668
+ const { verbose: t, prefix: n } = this.options;
669
+ t && console.info(n, ...s);
670
+ }
671
+ error(...s) {
672
+ const { verbose: t, prefix: n } = this.options;
673
+ t && console.error(n, ...s);
674
+ }
675
+ }
676
+ const Vt = [
677
+ "nose",
678
+ "leftEyeInner",
679
+ "leftEye",
680
+ "leftEyeOuter",
681
+ "rightEyeInner",
682
+ "rightEye",
683
+ "rightEyeOuter",
684
+ "leftEar",
685
+ "rightEar",
686
+ "mouthLeft",
687
+ "mouthRight",
688
+ "leftShoulder",
689
+ "rightShoulder",
690
+ "leftElbow",
691
+ "rightElbow",
692
+ "leftWrist",
693
+ "rightWrist",
694
+ "leftPinky",
695
+ "rightPinky",
696
+ "leftIndex",
697
+ "rightIndex",
698
+ "leftThumb",
699
+ "rightThumb",
700
+ "leftHip",
701
+ "rightHip",
702
+ "leftKnee",
703
+ "rightKnee",
704
+ "leftAnkle",
705
+ "rightAnkle",
706
+ "leftHeel",
707
+ "rightHeel",
708
+ "leftFootIndex",
709
+ "rightFootIndex"
710
+ ], pe = Object.fromEntries(
711
+ Vt.map((e, s) => [e, s])
712
+ ), gn = (e) => e === "mouthLeft" ? "mouthRight" : e === "mouthRight" ? "mouthLeft" : e.startsWith("left") ? `right${e.slice(4)}` : e.startsWith("right") ? `left${e.slice(5)}` : e, pn = Object.freeze(
713
+ Vt.map((e) => pe[gn(e)])
714
+ ), yn = (e, s = { x: 0, y: 0, z: 0 }) => (s.x = e.x * 100, s.y = -e.y * 100, s.z = -e.z * 100, s), wn = (e, s, t) => {
715
+ if (!s) return { ...e, timestampMs: t };
716
+ const n = (i) => i.map((r, o) => i[pn[o] ?? o] ?? i[o]);
717
+ return {
718
+ world: n(e.world),
719
+ image: n(e.image),
720
+ visibility: n(e.visibility),
721
+ timestampMs: t
722
+ };
723
+ }, vn = Object.freeze({
724
+ holdMs: 250,
725
+ maxJump: 1,
726
+ duplicate: 0.1,
727
+ confirm: 3,
728
+ confirmMs: 100
729
+ }), xn = 1, Sn = 1.2, Mn = 200, ze = [pe.leftShoulder, pe.rightShoulder, pe.leftHip, pe.rightHip], bn = (e, s) => {
730
+ const t = ze.map((w) => e.image[w]);
731
+ if (t.some((w) => !w)) return null;
732
+ const n = (w) => ({ x: w.x * s, y: w.y }), [i, r, o, a] = t.map(n), d = { x: (i.x + r.x) / 2, y: (i.y + r.y) / 2 }, l = { x: (o.x + a.x) / 2, y: (o.y + a.y) / 2 }, h = Math.max(
733
+ Math.hypot(d.x - l.x, d.y - l.y),
734
+ Math.hypot(i.x - r.x, i.y - r.y)
735
+ );
736
+ if (!(h > 1e-6)) return null;
737
+ const m = ze.reduce((w, M) => w + (e.visibility[M] ?? 0), 0) / ze.length;
738
+ return {
739
+ pose: e,
740
+ center: { x: (d.x + l.x) / 2, y: (d.y + l.y) / 2 },
741
+ size: h,
742
+ visibility: m
743
+ };
744
+ };
745
+ class kn {
746
+ constructor(s = {}) {
747
+ u(this, "settings");
748
+ u(this, "tracks", []);
749
+ u(this, "nextId", 1);
750
+ this.settings = { ...vn, ...s };
751
+ }
752
+ /**
753
+ * One detection's bodies (any order) at `nowMs`; `aspect` is the analysed
754
+ * frame's width / height. Returns every tracked body, by id.
755
+ */
756
+ update(s, t, n = 1) {
757
+ const { holdMs: i, maxJump: r, duplicate: o, confirm: a, confirmMs: d } = this.settings, l = this.dedupe(
758
+ s.map((g) => bn(g, n)).filter((g) => !!g),
759
+ o
760
+ ), h = l.map(
761
+ (g) => this.tracks.map((p) => {
762
+ const v = Math.min(Math.max(t - p.lastSeenMs, 0), Mn), A = p.center.x + p.velocity.x * v, E = p.center.y + p.velocity.y * v, B = Math.max(p.size, g.size), K = Math.hypot(g.center.x - A, g.center.y - E) / B;
763
+ return K > r ? 1 / 0 : K + xn * Math.abs(Math.log(g.size / p.size));
764
+ })
765
+ );
766
+ let m = l.map(() => -1), w = 1 / 0;
767
+ const M = [], x = /* @__PURE__ */ new Set(), b = (g, p) => {
768
+ if (!(p >= w)) {
769
+ if (g === l.length) {
770
+ m = [...M], w = p;
771
+ return;
772
+ }
773
+ for (let v = 0; v < this.tracks.length; v += 1) {
774
+ const A = h[g][v];
775
+ x.has(v) || A === 1 / 0 || (x.add(v), M[g] = v, b(g + 1, p + A), x.delete(v));
776
+ }
777
+ M[g] = -1, b(g + 1, p + Sn);
778
+ }
779
+ };
780
+ b(0, 0);
781
+ const T = /* @__PURE__ */ new Set(), y = !this.tracks.some((g) => g.id !== null) ? l.reduce(
782
+ (g, p, v) => m[v] < 0 && (!g || p.visibility > g.visibility) ? p : g,
783
+ null
784
+ ) : null;
785
+ l.forEach((g, p) => {
786
+ const v = m[p] >= 0 ? this.tracks[m[p]] : null;
787
+ if (!v) {
788
+ const E = {
789
+ id: null,
790
+ hits: 1,
791
+ firstSeenMs: t,
792
+ pose: g.pose,
793
+ center: g.center,
794
+ size: g.size,
795
+ velocity: { x: 0, y: 0 },
796
+ lastSeenMs: t
797
+ };
798
+ (g === y || a <= 1 && d <= 0) && this.confirm(E), this.tracks.push(E), T.add(E);
799
+ return;
800
+ }
801
+ v.hits += 1, v.id === null && v.hits >= a && t - v.firstSeenMs >= d && this.confirm(v);
802
+ const A = t - v.lastSeenMs;
803
+ A > 0 && (v.velocity = {
804
+ x: (v.velocity.x + (g.center.x - v.center.x) / A) / 2,
805
+ y: (v.velocity.y + (g.center.y - v.center.y) / A) / 2
806
+ }), v.pose = g.pose, v.center = g.center, v.size = g.size, v.lastSeenMs = t, T.add(v);
807
+ }), this.tracks = this.tracks.filter(
808
+ (g) => T.has(g) || g.id !== null && t - g.lastSeenMs <= i
809
+ );
810
+ for (const g of this.tracks) T.has(g) || (g.hits = 0);
811
+ return this.tracks.filter((g) => g.id !== null).map((g) => ({ id: g.id, pose: g.pose, held: !T.has(g) })).sort((g, p) => g.id - p.id);
812
+ }
813
+ confirm(s) {
814
+ s.id = this.nextId, this.nextId += 1;
815
+ }
816
+ /** Forget every body; ids keep counting up. */
817
+ reset() {
818
+ this.tracks = [];
819
+ }
820
+ /** One person detected twice (overlapping tracking regions): keep the more visible. */
821
+ dedupe(s, t) {
822
+ const n = [], i = [...s].sort((r, o) => o.visibility - r.visibility);
823
+ for (const r of i)
824
+ n.some(
825
+ (a) => Math.hypot(a.center.x - r.center.x, a.center.y - r.center.y) / Math.max(a.size, r.size) < t && Math.abs(Math.log(a.size / r.size)) < 0.1
826
+ ) || n.push(r);
827
+ return s.filter((r) => n.includes(r));
828
+ }
829
+ }
830
+ const Mt = (e, s) => {
831
+ let t = 1;
832
+ for (const n of e) Number.isFinite(n) && (t = Math.max(t, Math.round(n)));
833
+ return Math.min(t, s);
834
+ }, V = {
835
+ width: 720,
836
+ height: 1280
837
+ }, J = 32, Cn = 0.5, Ce = {
838
+ enabled: !0,
839
+ position: { x: 0, y: 0 },
840
+ size: { width: 680, height: 1230 },
841
+ pivot: [0.5, 0.5],
842
+ rotation: 0,
843
+ scale2D: { x: 1, y: 1 },
844
+ referencePixelsPerUnit: J,
845
+ renderOrder: 999,
846
+ overlay: !0,
847
+ visible: !0,
848
+ showTransformGuides: !1
849
+ }, Tn = Math.PI / 180, bt = (e, s) => s <= 0 ? e : Math.round(e / s) * s, pr = ({
850
+ transform: e,
851
+ parentSize: s,
852
+ root: t = V,
853
+ snapIncrement: n = Cn
854
+ }) => {
855
+ const r = Math.min(s.width / t.width, s.height / t.height) * (J / e.referencePixelsPerUnit), o = e.size.width * e.scale2D.x * r, a = e.size.height * e.scale2D.y * r, d = bt(e.position.x, n) * r, l = bt(e.position.y, n) * r, h = (e.pivot[0] - 0.5) * o, m = (e.pivot[1] - 0.5) * a;
856
+ return {
857
+ center: [d - h, l - m, 0],
858
+ size: [o, a, 1],
859
+ rotation: [0, 0, e.rotation * Tn],
860
+ pivotOffset: [h / Math.max(o, 1e-6), m / Math.max(a, 1e-6), 0],
861
+ aspect: o > 0 && a > 0 ? Math.abs(o / a) : 1
862
+ };
863
+ }, yr = (e) => ({
864
+ ...Ce,
865
+ ...e,
866
+ position: { ...Ce.position, ...e == null ? void 0 : e.position },
867
+ size: { ...Ce.size, ...e == null ? void 0 : e.size },
868
+ scale2D: { ...Ce.scale2D, ...e == null ? void 0 : e.scale2D }
869
+ }), U = (e, s) => {
870
+ if (!Number.isFinite(e) || e <= 0) throw new RangeError(`${s} must be positive`);
871
+ return e;
872
+ }, En = (e, s) => {
873
+ const t = U(s.width, "root.width"), n = U(s.height, "root.height");
874
+ return !Number.isFinite(e.width) || !Number.isFinite(e.height) || e.width <= 0 || e.height <= 0 ? 0 : Math.min(e.width / t, e.height / n);
875
+ }, $e = (e, s, t, n) => s.width <= 0 || s.height <= 0 ? Object.assign(n, { x: 0, y: 0 }) : (U(t.width, "root.width"), U(t.height, "root.height"), n.x = (e.x / s.width - 0.5) * t.width, n.y = (0.5 - e.y / s.height) * t.height, n), et = (e, s, t, n) => s.width <= 0 || s.height <= 0 ? Object.assign(n, { x: 0, y: 0 }) : (U(t.width, "root.width"), U(t.height, "root.height"), n.x = (e.x / t.width + 0.5) * s.width, n.y = (0.5 - e.y / t.height) * s.height, n), Kt = ({
876
+ parentSize: e,
877
+ referencePixelsPerUnit: s = J,
878
+ root: t = V
879
+ }) => En(e, t) * (J / U(s, "referencePixelsPerUnit")), wr = (e, s) => e * Kt(s), vr = (e, s) => {
880
+ const t = Kt(s);
881
+ return t === 0 ? 0 : e / t;
882
+ }, xr = ({
883
+ point: e,
884
+ parentSize: s,
885
+ referencePixelsPerUnit: t = J,
886
+ root: n = V,
887
+ target: i = { x: 0, y: 0 }
888
+ }) => {
889
+ if (s.width <= 0 || s.height <= 0) return Object.assign(i, { x: 0, y: 0 });
890
+ const r = J / U(t, "referencePixelsPerUnit");
891
+ return i.x = e.x * (s.width / U(n.width, "root.width")) * r, i.y = e.y * (s.height / U(n.height, "root.height")) * r, i;
892
+ }, Sr = ({
893
+ point: e,
894
+ parentSize: s,
895
+ referencePixelsPerUnit: t = J,
896
+ root: n = V,
897
+ target: i = { x: 0, y: 0 }
898
+ }) => {
899
+ if (s.width <= 0 || s.height <= 0) return Object.assign(i, { x: 0, y: 0 });
900
+ const r = J / U(t, "referencePixelsPerUnit");
901
+ return i.x = e.x / (s.width / U(n.width, "root.width") * r), i.y = e.y / (s.height / U(n.height, "root.height") * r), i;
902
+ }, Mr = ({
903
+ point: e,
904
+ rect: s,
905
+ root: t = V,
906
+ target: n = { x: 0, y: 0 }
907
+ }) => $e({ x: e.x - s.left, y: e.y - s.top }, s, t, n), br = ({
908
+ point: e,
909
+ rect: s,
910
+ root: t = V,
911
+ target: n = { x: 0, y: 0 }
912
+ }) => (et(e, s, t, n), n.x += s.left, n.y += s.top, n), Gt = ({
913
+ point: e,
914
+ root: s = V,
915
+ target: t = { x: 0, y: 0 },
916
+ viewportSize: n
917
+ }) => $e(
918
+ { x: e.x * n.width, y: e.y * n.height },
919
+ n,
920
+ s,
921
+ t
922
+ ), Rn = ({
923
+ point: e,
924
+ root: s = V,
925
+ target: t = { x: 0, y: 0 },
926
+ viewportSize: n
927
+ }) => n.width <= 0 || n.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (et(e, n, s, t), t.x /= n.width, t.y /= n.height, t), kr = ({
928
+ point: e,
929
+ root: s = V,
930
+ target: t = { x: 0, y: 0 },
931
+ viewportSize: n
932
+ }) => Gt({
933
+ point: { x: (e.x + 1) / 2, y: (1 - e.y) / 2 },
934
+ viewportSize: n,
935
+ root: s,
936
+ target: t
937
+ }), Cr = ({
938
+ layout: e,
939
+ mirrored: s = !1,
940
+ point: t,
941
+ root: n = V,
942
+ target: i = { x: 0, y: 0 }
943
+ }) => {
944
+ if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
945
+ const r = e.offsetX + t.x * e.scale;
946
+ return $e(
947
+ {
948
+ x: s ? e.destination.width - r : r,
949
+ y: e.offsetY + t.y * e.scale
950
+ },
951
+ e.destination,
952
+ n,
953
+ i
954
+ );
955
+ }, Tr = ({
956
+ layout: e,
957
+ mirrored: s = !1,
958
+ point: t,
959
+ root: n = V,
960
+ target: i = { x: 0, y: 0 }
961
+ }) => {
962
+ if (e.scale <= 0) return Object.assign(i, { x: 0, y: 0 });
963
+ et(t, e.destination, n, i);
964
+ const r = s ? e.destination.width - i.x : i.x;
965
+ return i.x = (r - e.offsetX) / e.scale, i.y = (i.y - e.offsetY) / e.scale, i;
966
+ }, Te = new qs(), kt = new Us(), Ct = new zs(), Er = ({
967
+ camera: e,
968
+ point: s,
969
+ root: t = V,
970
+ target: n = { x: 0, y: 0, depth: 0 },
971
+ viewportSize: i
972
+ }) => (U(t.width, "root.width"), U(t.height, "root.height"), Te.set(s.x, s.y, s.z).project(e), n.x = Te.x * t.width / 2, n.y = Te.y * t.height / 2, n.depth = Te.z, n), Rr = ({
973
+ camera: e,
974
+ point: s,
975
+ root: t = V,
976
+ target: n = new Ws(),
977
+ viewportSize: i
978
+ }) => (U(t.width, "root.width"), U(t.height, "root.height"), kt.set(s.x * 2 / t.width, s.y * 2 / t.height), Ct.setFromCamera(kt, e), n.copy(Ct.ray)), Ar = (e, s) => ue({ x: e.x, y: e.y, z: e.z ?? 0 }, s), An = (e, s = { x: 0, y: 0 }) => {
979
+ const t = Gs(e);
980
+ return s.x = t.x, s.y = t.y, s.z = t.z, s;
981
+ }, Ir = (e, s, t = { x: 0, y: 0 }) => (t.x = e.x * s.width, t.y = e.y * s.height, t), Fr = (e, s, t = { x: 0, y: 0 }) => s.width <= 0 || s.height <= 0 ? Object.assign(t, { x: 0, y: 0 }) : (t.x = e.x / s.width, t.y = e.y / s.height, t), Pr = (e, s, t = {}) => Gt({
982
+ point: e,
983
+ viewportSize: s,
984
+ root: t.root,
985
+ target: t.target
986
+ }), _r = (e, s, t = {}) => {
987
+ const n = t.target ?? { x: 0, y: 0 };
988
+ return Rn({ point: e, viewportSize: s, root: t.root, target: n }), n;
989
+ }, In = { selection: "index", index: 0 }, Tt = Object.freeze({
990
+ face: { max: 10, default: 1, option: "numFaces" },
991
+ hand: { max: 2, default: 2, option: null },
992
+ gesture: { max: 1, default: 1, option: null },
993
+ body: { max: 2, default: 1, option: "numBodies" },
994
+ holistic: { max: 1, default: 1, option: null }
995
+ }), Fn = { center: null }, de = (e, s) => Math.hypot(e.x - s.x, e.y - s.y), Ee = (e) => ({
996
+ center: { ...e.center },
997
+ ...e.label === void 0 ? {} : { label: e.label },
998
+ ...e.id === void 0 ? {} : { id: e.id }
999
+ }), Et = (e, s, t) => {
1000
+ if (!e.length) return null;
1001
+ switch (s) {
1002
+ case "largest":
1003
+ return e.reduce((n, i) => i.size > n.size ? i : n);
1004
+ case "nearest-center":
1005
+ return e.reduce(
1006
+ (n, i) => de(i.center, { x: 0.5, y: 0.5 }) < de(n.center, { x: 0.5, y: 0.5 }) ? i : n
1007
+ );
1008
+ case "leftmost":
1009
+ return e.reduce((n, i) => i.center.x < n.center.x ? i : n);
1010
+ case "rightmost":
1011
+ return e.reduce((n, i) => i.center.x > n.center.x ? i : n);
1012
+ default:
1013
+ return e.find((n) => n.index === t) ?? null;
1014
+ }
1015
+ }, Dr = (e, s = In, t = Fn) => {
1016
+ const n = s.index ?? 0;
1017
+ if (s.selection !== "sticky") {
1018
+ const a = Et(e, s.selection, n);
1019
+ return {
1020
+ index: (a == null ? void 0 : a.index) ?? null,
1021
+ reason: a ? s.selection : "none",
1022
+ memory: a ? Ee(a) : t
1023
+ };
1024
+ }
1025
+ const i = t.id === void 0 ? void 0 : e.find((a) => a.id === t.id);
1026
+ if (i) return { index: i.index, reason: "sticky", memory: Ee(i) };
1027
+ const r = s.stickyRadius ?? 0.2;
1028
+ if (t.center) {
1029
+ const a = t.center, d = e.filter((m) => de(m.center, a) <= r).sort((m, w) => de(m.center, a) - de(w.center, a)), h = (t.label ? d.find((m) => m.label === t.label) : void 0) ?? d[0];
1030
+ if (h)
1031
+ return { index: h.index, reason: "sticky", memory: Ee(h) };
1032
+ }
1033
+ const o = Et(e, s.fallback ?? "largest", n);
1034
+ return {
1035
+ index: (o == null ? void 0 : o.index) ?? null,
1036
+ reason: o ? "sticky-fallback" : "none",
1037
+ // Keep the old memory on a miss so a brief dropout does not forget the subject.
1038
+ memory: o ? Ee(o) : t
1039
+ };
1040
+ }, Or = (e) => e.map((s, t) => {
1041
+ let n = 1 / 0, i = -1 / 0, r = 1 / 0, o = -1 / 0;
1042
+ for (const d of s)
1043
+ d.x < n && (n = d.x), d.x > i && (i = d.x), d.y < r && (r = d.y), d.y > o && (o = d.y);
1044
+ const a = s.length > 0 && Number.isFinite(n);
1045
+ return {
1046
+ index: t,
1047
+ center: a ? { x: (n + i) / 2, y: (r + o) / 2 } : { x: 0.5, y: 0.5 },
1048
+ size: a ? i - n : 0
1049
+ };
1050
+ }), Pn = (e) => e.map((s, t) => {
1051
+ const n = (s.coordinates ?? []).map((l) => An(l));
1052
+ let i = 1 / 0, r = -1 / 0, o = 1 / 0, a = -1 / 0;
1053
+ for (const l of n)
1054
+ l.x < i && (i = l.x), l.x > r && (r = l.x), l.y < o && (o = l.y), l.y > a && (a = l.y);
1055
+ const d = n.length > 0;
1056
+ return {
1057
+ index: t,
1058
+ center: d ? { x: (i + r) / 2, y: (o + a) / 2 } : { x: 0.5, y: 0.5 },
1059
+ size: d ? Math.max(r - i, a - o) : 0,
1060
+ ...s.label ? { label: s.label } : {}
1061
+ };
1062
+ }), Lr = (e) => Pn(e.map((s) => ({ coordinates: s.pose.image }))).map((s, t) => ({
1063
+ ...s,
1064
+ id: e[t].id
1065
+ })), Nr = (e, s, t = 0.35) => {
1066
+ const n = [];
1067
+ for (const o of e)
1068
+ for (const a of s) {
1069
+ const d = de(o.center, a.center);
1070
+ d <= t && n.push({ primaryIndex: o.index, secondaryIndex: a.index, distance: d });
1071
+ }
1072
+ n.sort((o, a) => o.distance - a.distance);
1073
+ const i = /* @__PURE__ */ new Set(), r = /* @__PURE__ */ new Set();
1074
+ return n.filter((o) => i.has(o.primaryIndex) || r.has(o.secondaryIndex) ? !1 : (i.add(o.primaryIndex), r.add(o.secondaryIndex), !0));
1075
+ }, Rt = new z.Vector3(), We = new z.Vector3(), Xt = (e, s, t, n, i) => {
1076
+ Rt.set(e, s, 0).unproject(t), We.copy(Rt).sub(t.position).normalize();
1077
+ const r = (n - t.position.z) / We.z;
1078
+ return i.copy(t.position).addScaledVector(We, r);
1079
+ }, _n = (e, s, t = new z.Vector3(), n = 0) => Xt((e.x - 0.5) * 2, (0.5 - e.y) * 2, s, n, t), Br = (e, s, t = new z.Vector3(), n = 0) => Xt(e.x, e.y, s, n, t), j = new z.Vector3(), Hr = (e, s, t = { x: 0, y: 0, z: 0 }) => (j.set(e.x, e.y, e.z).project(s), t.x = j.x / 2 + 0.5, t.y = 0.5 - j.y / 2, t.z = j.z, t), Ur = (e, s, t = { x: 0, y: 0, z: 0 }) => (j.set(e.x, e.y, e.z).project(s), t.x = j.x, t.y = j.y, t.z = j.z, t), qe = (e, s, t) => _n(e, s, t, 0), Dn = (e, s, t = 0.2) => t * s + (1 - t) * e;
1080
+ class we {
1081
+ constructor(s) {
1082
+ u(this, "canvas");
1083
+ u(this, "scale", 1);
1084
+ this.maxDimension = s;
1085
+ }
1086
+ /** Multiply the cap (0.25..1); the adaptive-quality tier sets it. */
1087
+ setScale(s) {
1088
+ this.scale = Math.min(1, Math.max(0.25, Number.isFinite(s) && s > 0 ? s : 1));
1089
+ }
1090
+ /**
1091
+ * Returns a downscaled copy of `source` capped to `maxDimension` on its
1092
+ * longest side (or `source` unchanged if it's already within the cap, or if a
1093
+ * 2D context can't be obtained). The returned canvas is reused across calls.
1094
+ */
1095
+ draw(s) {
1096
+ const t = s.width, n = s.height, i = Math.min(
1097
+ 1,
1098
+ this.maxDimension * this.scale / Math.max(t, n)
1099
+ );
1100
+ if (i >= 1) return s;
1101
+ const r = Math.max(1, Math.round(t * i)), o = Math.max(1, Math.round(n * i));
1102
+ (!this.canvas || this.canvas.width !== r || this.canvas.height !== o) && (this.canvas = new OffscreenCanvas(r, o));
1103
+ const a = this.canvas.getContext("2d");
1104
+ return a ? (a.setTransform(1, 0, 0, 1, 0, 0), a.clearRect(0, 0, r, o), a.drawImage(s, 0, 0, r, o), this.canvas) : s;
1105
+ }
1106
+ dispose() {
1107
+ this.canvas = void 0;
1108
+ }
1109
+ }
1110
+ const On = {
1111
+ "/assets/xr/models/face_tracking.task": "sha384-tYQh+yJE8llY+zO4RviZmWaSKs5W9tsB0ix5rjQVpF5/CLTqmwtP7bYtkUi2w65P",
1112
+ "/assets/xr/models/hand_tracking.task": "sha384-uWvruVKd887ov8k43S+DBHCsi7UXXS+CKvvdM1PX00rjPzx/B0QrAPfJ1U9yKcze",
1113
+ "/assets/xr/models/gesture_tracking.task": "sha384-2zuseP9JKKWAYlWQGKA2N+ooabB8V/yIxu23Mv8mtY7SowcySB+xKiOmqBhVvlUC",
1114
+ "/assets/xr/models/body_tracking.task": "sha384-3Wk9dvRYo36b3Nc9xVjKamb4wCKt9FwiPjcHKfrvyJL/jXoGs+uRLnii6yjWLKul",
1115
+ "/assets/xr/models/segmentation.tflite": "sha384-A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5",
1116
+ "/assets/xr/3d-models/head-occluder-v2.glb": "sha384-+0G60Q6EBVE6hpITxGzQgofAeKexPltpsfPq5T5et9GGBjRhFP5HOdsKAhe73OaI",
1117
+ // v3: canonical-frame head (first 468 vertices = the canonical face landmarks),
1118
+ // authored in assets-src/head-occluder/head-occluder-v3.blend. Hash of the
1119
+ // exported GLB; the CDN copy must be byte-identical to example/src/assets/models.
1120
+ "/assets/xr/3d-models/head-occluder-v3.glb": "sha384-bmKKYb7k1qsGqkOSUBwv3oqI9eOche97/OvRxXDxrqZAgqpy+4PJ5HU9O94lrjFO",
1121
+ // Shoulder / upper-torso occluder in the canonical torso frame (same .blend).
1122
+ "/assets/xr/3d-models/shoulder-occluder-v1.glb": "sha384-iXxOvC+IoXfgpf8S/JSsV6lLzzLs6vtmaslJy7R0iLtl5Yb17U+/ATfGdhpmamae",
1123
+ // SDK-hosted rig models (lib/assets/sdkModels.ts): the CDN copies must be
1124
+ // byte-identical to example/src/assets/models/{hand-v1,glove-v1,ybot}.glb.
1125
+ // Upload pending: the default URLs fail closed until then.
1126
+ "/assets/xr/3d-models/hand-v1.glb": "sha384-noiRM38+PSoOZVgKaRLPf1001gHN38vMDPkSX2mL/Wgtj9o7TP/L05rHs6ubsGIK",
1127
+ "/assets/xr/3d-models/glove-v1.glb": "sha384-dZkRdB4URmKS2RBaDb4A7E95pLt4KKLlkxKsqA6L5N8elSbfiyyBoi7S9GcSVbDJ",
1128
+ "/assets/xr/3d-models/ybot-v1.glb": "sha384-pJY/JqDrnL8qPVtTC52G1GVsbBwBkEN5Z2TX3mm921l/iLsFTJDHbEMWcLd+icZ9",
1129
+ // Category segmenters behind XRModel.SEMANTIC_SEGMENTATION. The same bytes
1130
+ // are pinned under the SDK CDN paths (not yet published) and under
1131
+ // MediaPipe's published paths, which the presets load by default.
1132
+ "/assets/xr/models/hair_segmenter.tflite": "sha384-1Eu/EdJcYV/7talPYVVbxPZBLg7UIxqsKisUNh/pEsyvAuUcE49HuqijSXWSHXHK",
1133
+ "/mediapipe-models/image_segmenter/hair_segmenter/float32/latest/hair_segmenter.tflite": "sha384-1Eu/EdJcYV/7talPYVVbxPZBLg7UIxqsKisUNh/pEsyvAuUcE49HuqijSXWSHXHK",
1134
+ "/assets/xr/models/selfie_multiclass_256x256.tflite": "sha384-LPLPyzBZ6TTE8146rnDx8CZ5LykB8memkmeO8FNVbGlNthvlUltn3W3KeJmtq9bL",
1135
+ "/mediapipe-models/image_segmenter/selfie_multiclass_256x256/float32/latest/selfie_multiclass_256x256.tflite": "sha384-LPLPyzBZ6TTE8146rnDx8CZ5LykB8memkmeO8FNVbGlNthvlUltn3W3KeJmtq9bL",
1136
+ // Fingernail segmenter behind the `nails` preset (assets-src/nail-segmenter):
1137
+ // the CDN copy must be byte-identical to example/src/assets/models.
1138
+ "/assets/xr/models/nail_segmenter_v1.tflite": "sha384-sxkDgbQcK1Q/bxxzAHGvmSG00wm11UlrlH9dS242lo9QGBqBCEr4zj6sZE3mND43",
1139
+ // MediaPipe Holistic Landmarker (face + hands + pose in one graph) behind
1140
+ // XRModel.HOLISTIC_TRACKER. Same bytes pinned under the SDK CDN path (not yet
1141
+ // published) and MediaPipe's published path, which the tracker loads by default.
1142
+ "/assets/xr/models/holistic_landmarker.task": "sha384-6Y2fQ5yP5QtlvJIasfv0fHEyoMqRYYpLtEpsyeXjYDOuFCEXfKIZPZSXq8TLXmsg",
1143
+ "/mediapipe-models/holistic_landmarker/holistic_landmarker/float16/latest/holistic_landmarker.task": "sha384-6Y2fQ5yP5QtlvJIasfv0fHEyoMqRYYpLtEpsyeXjYDOuFCEXfKIZPZSXq8TLXmsg",
1144
+ "/assets/sdk/face/v1/canonical_face_model.obj": "sha384-xP8YM/72TXKvbMptXB9a8JUlUf3MZQ8uLurExrsZc05v6/P5RrsaNGMUYS/BZx8A",
1145
+ "/opencv/facial_expression_recognition/resolve/main/facial_expression_recognition_mobilefacenet_2022july_int8.onnx": "sha384-g8mtFubiIc/yhqi591RsxD76AJLw2CfYgKhKbVkIiFlwBmIyG7ZAIVyGPXafrDGB"
1146
+ };
1147
+ async function Ln(e, s) {
1148
+ const t = await fetch(e, s != null && s.signal ? { signal: s.signal } : void 0);
1149
+ if (!t.ok)
1150
+ throw new Error(`fetchAndVerify: ${t.status} ${e}`);
1151
+ const n = await t.arrayBuffer(), i = Hn(e);
1152
+ if (!i) {
1153
+ if (Nn(e))
1154
+ throw new Error(`[xr-sdk integrity] no SRI hash for SDK asset ${e}`);
1155
+ return console.warn(`[xr-sdk integrity] no SRI hash for ${e} — passing through`), n;
1156
+ }
1157
+ const r = await Un(n);
1158
+ if (r !== i)
1159
+ throw new Error(
1160
+ `[xr-sdk integrity] SRI mismatch for ${e}: expected ${i}, got ${r}`
1161
+ );
1162
+ return n;
1163
+ }
1164
+ function Nn(e) {
1165
+ try {
1166
+ return new URL(e).origin === new URL(W.assetStorageEndpoint).origin;
1167
+ } catch {
1168
+ return !1;
1169
+ }
1170
+ }
1171
+ async function ee(e) {
1172
+ const s = await Ln(e);
1173
+ return new Uint8Array(s);
1174
+ }
1175
+ const le = /* @__PURE__ */ new Map();
1176
+ function Bn(e) {
1177
+ let s = le.get(e);
1178
+ if (!s) {
1179
+ const i = { bytes: ee(e), holders: 0 };
1180
+ i.bytes.catch(() => {
1181
+ le.get(e) === i && le.delete(e);
1182
+ }), le.set(e, i), s = i;
1183
+ }
1184
+ const t = s;
1185
+ t.holders += 1;
1186
+ let n = !1;
1187
+ return {
1188
+ bytes: t.bytes,
1189
+ release: () => {
1190
+ n || (n = !0, t.holders -= 1, t.holders <= 0 && le.get(e) === t && le.delete(e));
1191
+ }
1192
+ };
1193
+ }
1194
+ function Hn(e) {
1195
+ try {
1196
+ const s = new URL(e);
1197
+ return On[s.pathname];
1198
+ } catch {
1199
+ return;
1200
+ }
1201
+ }
1202
+ async function Un(e) {
1203
+ const s = await crypto.subtle.digest("SHA-384", e), t = new Uint8Array(s);
1204
+ let n = "";
1205
+ for (let i = 0; i < t.byteLength; i++)
1206
+ n += String.fromCharCode(t[i]);
1207
+ return `sha384-${btoa(n)}`;
1208
+ }
1209
+ const Ve = /* @__PURE__ */ new Map();
1210
+ function te(e) {
1211
+ const s = e.wasmBinaryPath;
1212
+ let t = Ve.get(s);
1213
+ return t || (t = zn(s).catch(() => {
1214
+ Ve.delete(s);
1215
+ }), Ve.set(s, t)), t;
1216
+ }
1217
+ async function zn(e) {
1218
+ const s = await fetch(e, { credentials: "same-origin" });
1219
+ if (!s.ok || !s.body)
1220
+ throw new Error(`warmVisionWasm: ${s.status} ${e}`);
1221
+ const t = s.body.getReader();
1222
+ for (; ; ) {
1223
+ const { done: n } = await t.read();
1224
+ if (n) return;
1225
+ }
1226
+ }
1227
+ class se {
1228
+ constructor() {
1229
+ u(this, "disposed", !1);
1230
+ u(this, "paused", !1);
1231
+ u(this, "rafId", null);
1232
+ // Inference bookkeeping behind `getDiagnostics()`. Subclasses call
1233
+ // `recordInference(startMs)` right after their detect call and
1234
+ // `recordDetections(count, confidence)` after reading the result.
1235
+ u(this, "statInferenceMs", null);
1236
+ u(this, "statInferences", 0);
1237
+ u(this, "statWindowStart", 0);
1238
+ u(this, "statWindowCount", 0);
1239
+ u(this, "statFps", 0);
1240
+ u(this, "statSkipped", 0);
1241
+ u(this, "statDetections", null);
1242
+ u(this, "statConfidence", null);
1243
+ u(this, "statStatus", "ready");
1244
+ u(this, "statError", null);
1245
+ // Inference-rate throttle. `targetFrameIntervalMs` is 0 when uncapped
1246
+ // (detect every frame); a positive value skips detection until that many ms
1247
+ // have elapsed since the last inference. `run()` sets this from
1248
+ // `params.targetFps`; subclasses call `shouldRunInference()` in their RAF
1249
+ // loop to gate the expensive MediaPipe call.
1250
+ u(this, "targetFrameIntervalMs", 0);
1251
+ u(this, "lastInferenceMs", 0);
1252
+ /** Analysis-resolution multiplier (0.25..1) from the quality tier; subclasses read it where they downscale. */
1253
+ u(this, "analysisScale", 1);
1254
+ }
1255
+ /** Record one completed inference that started at `startMs` (`performance.now()`). */
1256
+ recordInference(s, t = performance.now()) {
1257
+ const n = t - s;
1258
+ this.statInferenceMs = n, this.statInferences += 1, this.statWindowCount += 1, this.statWindowStart === 0 && (this.statWindowStart = t);
1259
+ const i = t - this.statWindowStart;
1260
+ return i >= 1e3 && (this.statFps = this.statWindowCount * 1e3 / i, this.statWindowStart = t, this.statWindowCount = 0), n;
1261
+ }
1262
+ /** Record what the last inference found (subjects and the primary confidence). */
1263
+ recordDetections(s, t = null) {
1264
+ this.statDetections = s, this.statConfidence = t;
1265
+ }
1266
+ /** Record an inference failure (or clear it with `null`). */
1267
+ recordInferenceError(s) {
1268
+ this.statStatus = s ? "error" : "ready", this.statError = s;
1269
+ }
1270
+ /** Current health snapshot. Allocates a small object; sample it at UI rate, not per frame. */
1271
+ getDiagnostics() {
1272
+ const s = this.statWindowStart > 0 && performance.now() - this.statWindowStart > 1500;
1273
+ return {
1274
+ inferenceMs: this.statInferenceMs,
1275
+ inferenceFps: s ? 0 : this.statFps,
1276
+ inferences: this.statInferences,
1277
+ skippedFrames: this.statSkipped,
1278
+ detections: this.statDetections,
1279
+ confidence: this.statConfidence,
1280
+ status: this.statStatus,
1281
+ error: this.statError,
1282
+ paused: this.paused,
1283
+ disposed: this.disposed
1284
+ };
1285
+ }
1286
+ /** Clamp and store the analysis scale; subclasses with a downscaler forward it. */
1287
+ setAnalysisScale(s) {
1288
+ this.analysisScale = s !== void 0 && Number.isFinite(s) && s > 0 ? Math.min(1, Math.max(0.25, s)) : 1;
1289
+ }
1290
+ /** Set the per-frame inference cap. fps <= 0 (or undefined) → uncapped. */
1291
+ setTargetFps(s) {
1292
+ this.targetFrameIntervalMs = s && s > 0 ? 1e3 / s : 0;
1293
+ }
1294
+ /**
1295
+ * True if enough time has elapsed to run inference this frame (and records
1296
+ * the timestamp). Always true when uncapped. Call once per RAF tick, right
1297
+ * before the detect call; skip the detect (but keep rescheduling RAF) when
1298
+ * it returns false.
1299
+ */
1300
+ shouldRunInference() {
1301
+ if (this.targetFrameIntervalMs <= 0) return !0;
1302
+ const s = performance.now();
1303
+ return s - this.lastInferenceMs < this.targetFrameIntervalMs ? (this.statSkipped += 1, !1) : (this.lastInferenceMs = s, !0);
1304
+ }
1305
+ // load models
1306
+ async initialize(s) {
1307
+ }
1308
+ // setup for running + start running
1309
+ async run(s) {
1310
+ }
1311
+ // get model's data while processing
1312
+ getModelNode() {
1313
+ return {};
1314
+ }
1315
+ async getPerformanceData() {
1316
+ return {
1317
+ name: this.constructor.name,
1318
+ processingTime: null
1319
+ };
1320
+ }
1321
+ // Cancel the per-frame RAF loop without releasing MediaPipe resources or
1322
+ // dropping refs. Subclasses' process* methods check `paused` and return
1323
+ // without rescheduling. Idempotent.
1324
+ pause() {
1325
+ this.paused = !0, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
1326
+ }
1327
+ // Resume a paused loop by running the process function once. Subclasses
1328
+ // override to kick their specific process* method. Idempotent — no-op if
1329
+ // not paused. Calling resume() before run() is a no-op.
1330
+ resume() {
1331
+ this.paused = !1;
1332
+ }
1333
+ // Release MediaPipe landmarkers, cancel rAF loops, drop refs.
1334
+ // Subclasses MUST override and call super.dispose() at the end.
1335
+ dispose() {
1336
+ this.disposed = !0, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
1337
+ }
1338
+ }
1339
+ const Wn = 768, Ke = (e) => e > 1 ? "IMAGE" : "VIDEO";
1340
+ class qn extends se {
1341
+ constructor() {
1342
+ super();
1343
+ u(this, "landmarker", null);
1344
+ u(this, "processingTime", null);
1345
+ u(this, "coordinates");
1346
+ u(this, "visibility");
1347
+ /** Per body, sided as the person's own left / right (see `anatomicalBodyPose`). */
1348
+ u(this, "poses", []);
1349
+ /** The same bodies with a stable id each (`BodyIdentity`), by id. */
1350
+ u(this, "bodies", []);
1351
+ u(this, "identity", new kn());
1352
+ /** How many bodies the landmarker looks for now, and what each consumer asked for. */
1353
+ u(this, "numPoses", 1);
1354
+ u(this, "bodyRequests", /* @__PURE__ */ new Map());
1355
+ /** While `setOptions` rebuilds the landmarker, inference waits. */
1356
+ u(this, "reconfiguring", !1);
1357
+ u(this, "getSource");
1358
+ u(this, "sourceCanvas");
1359
+ u(this, "downscaler", new we(Wn));
1360
+ }
1361
+ async getBodyData() {
1362
+ var w;
1363
+ if (!this.landmarker || !this.sourceCanvas)
1364
+ return;
1365
+ const t = this.downscaler.draw(this.sourceCanvas), n = performance.now(), i = Ke(this.numPoses) === "IMAGE" ? this.landmarker.detect(t) : this.landmarker.detectForVideo(t, n), r = performance.now();
1366
+ this.processingTime = r - n, this.recordInference(n, r);
1367
+ const o = i.landmarks, a = o == null ? void 0 : o[0];
1368
+ this.recordDetections(
1369
+ (o == null ? void 0 : o.length) ?? 0,
1370
+ a && a.length ? a.reduce((M, x) => M + (x.visibility ?? 0), 0) / a.length : null
1371
+ );
1372
+ const d = [], l = [], h = [], m = Se((w = this.getSource) == null ? void 0 : w.call(this));
1373
+ if (o)
1374
+ return o.forEach((M, x) => {
1375
+ var T;
1376
+ d[x] || (d[x] = [], l[x] = []), M.forEach((R) => {
1377
+ d[x].push(ue(R)), l[x].push(R.visibility ?? 1);
1378
+ });
1379
+ const b = (((T = i.worldLandmarks) == null ? void 0 : T[x]) ?? []).map(
1380
+ (R) => yn(R)
1381
+ );
1382
+ b.length === M.length && (h[x] = wn(
1383
+ { world: b, image: d[x], visibility: l[x] },
1384
+ m,
1385
+ n
1386
+ ));
1387
+ }), {
1388
+ coordinatesList: d,
1389
+ visibilityList: l,
1390
+ poses: h
1391
+ };
1392
+ }
1393
+ async processBodyTracking() {
1394
+ var t;
1395
+ if (!(this.disposed || this.paused || !this.landmarker)) {
1396
+ if (!this.reconfiguring && this.shouldRunInference()) {
1397
+ const n = await this.getBodyData();
1398
+ if (n) {
1399
+ this.coordinates = n.coordinatesList, this.visibility = n.visibilityList, this.poses = n.poses;
1400
+ const i = this.sourceCanvas, r = i && i.height > 0 ? i.width / i.height : 1;
1401
+ this.bodies = this.identity.update(
1402
+ n.poses.filter(Boolean),
1403
+ ((t = n.poses.find(Boolean)) == null ? void 0 : t.timestampMs) ?? performance.now(),
1404
+ r
1405
+ );
1406
+ }
1407
+ }
1408
+ this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processBodyTracking.bind(this)));
1409
+ }
1410
+ }
1411
+ resume() {
1412
+ this.paused && (super.resume(), this.processBodyTracking());
1413
+ }
1414
+ dispose() {
1415
+ if (super.dispose(), this.landmarker) {
1416
+ try {
1417
+ this.landmarker.close();
1418
+ } catch {
1419
+ }
1420
+ this.landmarker = null;
1421
+ }
1422
+ this.sourceCanvas = void 0, this.downscaler.dispose(), this.coordinates = void 0, this.visibility = void 0, this.poses = [], this.bodies = [], this.identity.reset(), this.bodyRequests.clear(), this.getSource = void 0;
1423
+ }
1424
+ getLandmarks2D(t = 0) {
1425
+ if (this.coordinates)
1426
+ return this.coordinates[t];
1427
+ }
1428
+ getVisibility(t = 0) {
1429
+ var n;
1430
+ return (n = this.visibility) == null ? void 0 : n[t];
1431
+ }
1432
+ getBodyPose(t = 0) {
1433
+ return this.poses[t] ?? null;
1434
+ }
1435
+ getBodyPoseById(t) {
1436
+ var n;
1437
+ return ((n = this.bodies.find((i) => i.id === t)) == null ? void 0 : n.pose) ?? null;
1438
+ }
1439
+ /** Records `owner`'s wish for `count` bodies; the landmarker looks for the most asked. */
1440
+ requestBodies(t, n) {
1441
+ return this.bodyRequests.set(t, n), this.applyNumBodies(), () => {
1442
+ this.bodyRequests.delete(t) && this.applyNumBodies();
1443
+ };
1444
+ }
1445
+ async applyNumBodies() {
1446
+ const t = Mt(this.bodyRequests.values(), Tt.body.max);
1447
+ if (!(t === this.numPoses || this.disposed || this.reconfiguring || !this.landmarker)) {
1448
+ this.reconfiguring = !0;
1449
+ try {
1450
+ await this.landmarker.setOptions({ numPoses: t, runningMode: Ke(t) }), this.numPoses = t;
1451
+ } catch (n) {
1452
+ console.warn("[BodyTrackingModel] numPoses change failed", n);
1453
+ return;
1454
+ } finally {
1455
+ this.reconfiguring = !1;
1456
+ }
1457
+ this.applyNumBodies();
1458
+ }
1459
+ }
1460
+ async initialize(t) {
1461
+ const n = await $.forVisionTasks(
1462
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
1463
+ ), [i] = await Promise.all([
1464
+ ee(
1465
+ new URL("/assets/xr/models/body_tracking.task", W.assetStorageEndpoint).toString()
1466
+ ),
1467
+ te(n)
1468
+ ]);
1469
+ t != null && t.numPoses && this.bodyRequests.set("options", t.numPoses);
1470
+ const r = Mt(this.bodyRequests.values(), Tt.body.max);
1471
+ this.landmarker = await Ds.createFromOptions(n, {
1472
+ baseOptions: {
1473
+ modelAssetBuffer: i,
1474
+ delegate: "GPU"
1475
+ },
1476
+ runningMode: Ke(r),
1477
+ numPoses: r
1478
+ }), this.numPoses = r, this.applyNumBodies();
1479
+ }
1480
+ async run({
1481
+ sourceCanvas: t,
1482
+ getSource: n,
1483
+ targetFps: i,
1484
+ analysisScale: r
1485
+ }) {
1486
+ this.getSource = n, this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = t, this.setTargetFps(i), this.rafId === null && await this.processBodyTracking();
1487
+ }
1488
+ getModelNode() {
1489
+ const t = this;
1490
+ return {
1491
+ getLandmarks2D: this.getLandmarks2D.bind(this),
1492
+ getVisibility: this.getVisibility.bind(this),
1493
+ getBodyPose: this.getBodyPose.bind(this),
1494
+ getBodies: () => this.bodies,
1495
+ getBodyPoseById: this.getBodyPoseById.bind(this),
1496
+ requestBodies: this.requestBodies.bind(this),
1497
+ get numBodies() {
1498
+ return t.numPoses;
1499
+ }
1500
+ };
1501
+ }
1502
+ async getPerformanceData() {
1503
+ return {
1504
+ name: this.constructor.name,
1505
+ processingTime: this.processingTime
1506
+ };
1507
+ }
1508
+ }
1509
+ const Yt = Symbol("xr.modelNodeSource"), zr = (e) => e[Yt] ?? e, Vn = 0.11, Kn = 4e-3, Gn = "/assets/xr/models/face_tracking.task", Xn = "/assets/xr/wasm", Yn = (e, s, t = !0) => t ? s.set(e.x, -e.y, e.z) : s.set(e.x, e.y, -e.z), jn = (e, s) => s.setFromRotationMatrix(e).normalize();
1510
+ class Qn extends se {
1511
+ constructor() {
1512
+ super();
1513
+ u(this, "landmarker", null);
1514
+ /** The face model bytes, held while this model is alive (shared with the still-image detector). */
1515
+ u(this, "modelBytes", null);
1516
+ u(this, "processingTime", null);
1517
+ u(this, "sourceCanvas");
1518
+ u(this, "analysisCanvas");
1519
+ u(this, "getSource");
1520
+ u(this, "detectionResults");
1521
+ u(this, "numFaces", 1);
1522
+ u(this, "cameras", []);
1523
+ // camera object to unproject each face's translation
1524
+ u(this, "faces", []);
1525
+ // Reused per-face work vectors. Allocated once per face index and mutated
1526
+ // in place each frame, so the published Face[] doesn't churn the GC at
1527
+ // 30+ fps. Per-face indexing means two faces don't alias each other's
1528
+ // transforms; consumers see "current value" each frame.
1529
+ u(this, "leftCheekScratch", []);
1530
+ u(this, "rightCheekScratch", []);
1531
+ // Reused per-frame rotation scratch (matrix -> quaternion -> mirror -> euler),
1532
+ // allocated once to avoid per-frame churn at 30+ fps.
1533
+ u(this, "rotMatrixScratch", new z.Matrix4());
1534
+ u(this, "rotQuatScratch", new z.Quaternion());
1535
+ u(this, "rotEulerScratch", new z.Euler());
1536
+ }
1537
+ extractAndUpdateFaceData(t) {
1538
+ var r;
1539
+ if (!t.faceLandmarks.length) {
1540
+ this.faces = [];
1541
+ return;
1542
+ }
1543
+ const n = t.faceLandmarks.length;
1544
+ this.faces.length > n && (this.faces.length = n, this.leftCheekScratch.length = n, this.rightCheekScratch.length = n);
1545
+ const i = Se((r = this.getSource) == null ? void 0 : r.call(this));
1546
+ for (; this.faces.length < n; )
1547
+ this.faces.push({
1548
+ transform: {
1549
+ position: new z.Vector3(),
1550
+ rotation: new z.Vector3(),
1551
+ quaternion: new z.Quaternion(),
1552
+ scale: new z.Vector3()
1553
+ },
1554
+ gestures: {},
1555
+ mirrored: i
1556
+ }), this.leftCheekScratch.push(new z.Vector3()), this.rightCheekScratch.push(new z.Vector3());
1557
+ for (let o = 0; o < n; o += 1)
1558
+ this.faces[o].mirrored = i;
1559
+ for (let o = 0; o < n; o += 1) {
1560
+ if (!this.cameras[o])
1561
+ continue;
1562
+ const a = this.faces[o], d = t.faceLandmarks[o], l = t.facialTransformationMatrixes[o];
1563
+ this.rotMatrixScratch.fromArray(l.data), jn(this.rotMatrixScratch, a.transform.quaternion), this.rotQuatScratch.copy(a.transform.quaternion), this.rotQuatScratch.set(
1564
+ -this.rotQuatScratch.x,
1565
+ this.rotQuatScratch.y,
1566
+ this.rotQuatScratch.z,
1567
+ this.rotQuatScratch.w
1568
+ ), this.rotEulerScratch.setFromQuaternion(this.rotQuatScratch, "XYZ"), Yn(this.rotEulerScratch, a.transform.rotation, i), qe(d[4], this.cameras[o], a.transform.position), qe(d[50], this.cameras[o], this.leftCheekScratch[o]), qe(d[280], this.cameras[o], this.rightCheekScratch[o]);
1569
+ const m = this.leftCheekScratch[o].distanceTo(this.rightCheekScratch[o]) * Vn, w = Math.abs(z.MathUtils.radToDeg(this.rotEulerScratch.y)), M = m + w * Kn, x = a.transform.scale.x, b = Dn(
1570
+ isNaN(x) ? 0 : x,
1571
+ M
1572
+ );
1573
+ a.transform.scale.set(b, b, b);
1574
+ const T = a.gestures, R = t.faceBlendshapes[o].categories;
1575
+ for (const y of R)
1576
+ T[y.categoryName] = y.score;
1577
+ }
1578
+ }
1579
+ async processFaceTracking() {
1580
+ if (this.disposed || this.paused || !this.landmarker || !this.sourceCanvas)
1581
+ return null;
1582
+ if (!this.shouldRunInference()) {
1583
+ this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this));
1584
+ return;
1585
+ }
1586
+ const t = Jn(this.numFaces) * this.analysisScale, n = this.sourceCanvas.width, i = this.sourceCanvas.height, r = Math.min(1, t / Math.max(n, i)), o = Math.max(1, Math.round(n * r)), a = Math.max(1, Math.round(i * r));
1587
+ (!this.analysisCanvas || this.analysisCanvas.width !== o || this.analysisCanvas.height !== a) && (this.analysisCanvas = new OffscreenCanvas(o, a));
1588
+ const d = this.analysisCanvas.getContext("2d");
1589
+ if (!d) {
1590
+ this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this));
1591
+ return;
1592
+ }
1593
+ d.setTransform(1, 0, 0, 1, 0, 0), d.clearRect(0, 0, o, a), d.drawImage(this.sourceCanvas, 0, 0, o, a);
1594
+ const l = performance.now(), h = this.landmarker.detectForVideo(this.analysisCanvas, l), m = performance.now();
1595
+ this.processingTime = m - l, this.recordInference(l, m), this.recordDetections(h.faceLandmarks.length, null), this.detectionResults = h, this.extractAndUpdateFaceData(h), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.processFaceTracking.bind(this)));
1596
+ }
1597
+ resume() {
1598
+ this.paused && (super.resume(), this.processFaceTracking());
1599
+ }
1600
+ dispose() {
1601
+ if (super.dispose(), this.landmarker) {
1602
+ try {
1603
+ this.landmarker.close();
1604
+ } catch {
1605
+ }
1606
+ this.landmarker = null;
1607
+ }
1608
+ this.releaseModelBytes(), this.sourceCanvas = void 0, this.getSource = void 0, this.analysisCanvas = void 0, this.detectionResults = void 0, this.processingTime = null, this.cameras = [], this.faces = [], this.leftCheekScratch = [], this.rightCheekScratch = [];
1609
+ }
1610
+ getFace(t = 0) {
1611
+ return this.faces[t];
1612
+ }
1613
+ getDetectionResults() {
1614
+ return this.detectionResults;
1615
+ }
1616
+ getRawFaceTrackingData(t = 0) {
1617
+ var n, i, r, o;
1618
+ if (this.detectionResults)
1619
+ return {
1620
+ landmarks: (n = this.detectionResults.faceLandmarks) == null ? void 0 : n[t],
1621
+ blendshapes: (r = (i = this.detectionResults.faceBlendshapes) == null ? void 0 : i[t]) == null ? void 0 : r.categories,
1622
+ transformationMatrix: (o = this.detectionResults.facialTransformationMatrixes) == null ? void 0 : o[t]
1623
+ };
1624
+ }
1625
+ async initialize(t) {
1626
+ var o;
1627
+ this.numFaces = (t == null ? void 0 : t.numFaces) || 1;
1628
+ const n = await $.forVisionTasks(
1629
+ new URL(Xn, W.assetStorageEndpoint).toString()
1630
+ );
1631
+ (o = this.modelBytes) == null || o.release();
1632
+ const i = Bn(
1633
+ new URL(Gn, W.assetStorageEndpoint).toString()
1634
+ );
1635
+ this.modelBytes = i;
1636
+ let r;
1637
+ try {
1638
+ const [a] = await Promise.all([i.bytes, te(n)]);
1639
+ r = await Os.createFromOptions(n, {
1640
+ baseOptions: {
1641
+ modelAssetBuffer: a,
1642
+ delegate: "GPU"
1643
+ },
1644
+ // Keep detection permissive for calibration workflows with dark webcam input.
1645
+ minFaceDetectionConfidence: 0.3,
1646
+ minFacePresenceConfidence: 0.3,
1647
+ minTrackingConfidence: 0.3,
1648
+ outputFaceBlendshapes: !0,
1649
+ outputFacialTransformationMatrixes: !0,
1650
+ runningMode: "VIDEO",
1651
+ numFaces: this.numFaces
1652
+ });
1653
+ } catch (a) {
1654
+ throw this.releaseModelBytes(i), a;
1655
+ }
1656
+ if (this.disposed) {
1657
+ r.close(), this.releaseModelBytes(i);
1658
+ return;
1659
+ }
1660
+ this.landmarker = r;
1661
+ }
1662
+ releaseModelBytes(t = this.modelBytes) {
1663
+ t == null || t.release(), this.modelBytes === t && (this.modelBytes = null);
1664
+ }
1665
+ async run({
1666
+ sourceCanvas: t,
1667
+ getSource: n,
1668
+ targetFps: i,
1669
+ analysisScale: r
1670
+ }) {
1671
+ this.sourceCanvas = t, this.getSource = n, this.setTargetFps(i), this.setAnalysisScale(r), this.analysisCanvas = void 0, this.rafId === null && this.processFaceTracking();
1672
+ }
1673
+ getModelNode() {
1674
+ const t = this, n = {
1675
+ get detectionResults() {
1676
+ return t.detectionResults;
1677
+ },
1678
+ get numFaces() {
1679
+ return t.numFaces;
1680
+ },
1681
+ getDetectionResults: this.getDetectionResults.bind(this),
1682
+ getFace: this.getFace.bind(this),
1683
+ getRawFaceTrackingData: this.getRawFaceTrackingData.bind(this),
1684
+ setCamera: (i, r = 0) => {
1685
+ this.cameras[r] = i;
1686
+ }
1687
+ };
1688
+ return Object.defineProperty(n, Yt, { value: t }), n;
1689
+ }
1690
+ async getPerformanceData() {
1691
+ return {
1692
+ name: this.constructor.name,
1693
+ processingTime: this.processingTime
1694
+ };
1695
+ }
1696
+ }
1697
+ const Jn = (e) => e > 1 ? 1024 : 512;
1698
+ var Y = /* @__PURE__ */ ((e) => (e.ClosedFist = "closed_fist", e.OpenPalm = "open_palm", e.PointingUp = "pointing_up", e.ThumbDown = "thumb_down", e.ThumbUp = "thumb_up", e.Victory = "victory", e.ILoveYou = "i_love_you", e.None = "none", e))(Y || {});
1699
+ const Zn = 512, $n = {
1700
+ Closed_Fist: Y.ClosedFist,
1701
+ Open_Palm: Y.OpenPalm,
1702
+ Pointing_Up: Y.PointingUp,
1703
+ Thumb_Down: Y.ThumbDown,
1704
+ Thumb_Up: Y.ThumbUp,
1705
+ Victory: Y.Victory,
1706
+ ILoveYou: Y.ILoveYou,
1707
+ None: Y.None
1708
+ }, ei = 15;
1709
+ class ti extends se {
1710
+ constructor() {
1711
+ super();
1712
+ u(this, "landmarker", null);
1713
+ u(this, "processingTime", null);
1714
+ u(this, "coordinates");
1715
+ u(this, "gesture");
1716
+ u(this, "sourceCanvas");
1717
+ u(this, "downscaler", new we(Zn));
1718
+ }
1719
+ async getGestureData() {
1720
+ var d, l;
1721
+ if (!this.landmarker || !this.sourceCanvas)
1722
+ return;
1723
+ const t = this.downscaler.draw(this.sourceCanvas), n = performance.now(), i = this.landmarker.recognizeForVideo(t, n), r = performance.now();
1724
+ this.processingTime = r - n, this.recordInference(n, r), this.recordDetections(i.landmarks.length, ((l = (d = i.gestures[0]) == null ? void 0 : d[0]) == null ? void 0 : l.score) ?? null);
1725
+ const o = i.landmarks[0], a = [];
1726
+ if (o) {
1727
+ const h = i.gestures[0][0].categoryName;
1728
+ return o.forEach((m) => {
1729
+ a.push(ue(m));
1730
+ }), {
1731
+ coordinates: a,
1732
+ gesture: $n[h]
1733
+ };
1734
+ }
1735
+ return { coordinates: void 0, gesture: void 0 };
1736
+ }
1737
+ async processGestureTracking() {
1738
+ if (!this.disposed) {
1739
+ if (this.shouldRunInference()) {
1740
+ const t = await this.getGestureData();
1741
+ t && (this.coordinates = t.coordinates, this.gesture = t.gesture);
1742
+ }
1743
+ this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processGestureTracking.bind(this)));
1744
+ }
1745
+ }
1746
+ resume() {
1747
+ this.paused && (super.resume(), this.processGestureTracking());
1748
+ }
1749
+ dispose() {
1750
+ if (super.dispose(), this.landmarker) {
1751
+ try {
1752
+ this.landmarker.close();
1753
+ } catch {
1754
+ }
1755
+ this.landmarker = null;
1756
+ }
1757
+ this.sourceCanvas = void 0, this.downscaler.dispose(), this.coordinates = void 0, this.gesture = void 0;
1758
+ }
1759
+ async initialize() {
1760
+ const t = await $.forVisionTasks(
1761
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
1762
+ ), [n] = await Promise.all([
1763
+ ee(
1764
+ new URL(
1765
+ "/assets/xr/models/gesture_tracking.task",
1766
+ W.assetStorageEndpoint
1767
+ ).toString()
1768
+ ),
1769
+ te(t)
1770
+ ]), i = await Ls.createFromOptions(t, {
1771
+ baseOptions: {
1772
+ modelAssetBuffer: n,
1773
+ delegate: "GPU"
1774
+ },
1775
+ runningMode: "VIDEO",
1776
+ numHands: 1
1777
+ });
1778
+ this.landmarker = i;
1779
+ }
1780
+ async run({ sourceCanvas: t, targetFps: n, analysisScale: i }) {
1781
+ this.setAnalysisScale(i), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = t, this.setTargetFps(n ?? ei), this.rafId === null && await this.processGestureTracking();
1782
+ }
1783
+ getModelNode() {
1784
+ const t = this;
1785
+ return {
1786
+ get coordinates() {
1787
+ return t.coordinates;
1788
+ },
1789
+ get gesture() {
1790
+ return t.gesture;
1791
+ }
1792
+ };
1793
+ }
1794
+ async getPerformanceData() {
1795
+ return {
1796
+ name: this.constructor.name,
1797
+ processingTime: this.processingTime
1798
+ };
1799
+ }
1800
+ }
1801
+ class si extends se {
1802
+ constructor() {
1803
+ super();
1804
+ u(this, "landmarker", null);
1805
+ u(this, "status", "loading");
1806
+ u(this, "error", null);
1807
+ u(this, "processingTime", null);
1808
+ u(this, "sourceCanvas");
1809
+ u(this, "getSource");
1810
+ u(this, "downscaler", new we(je().analysisMaxDimension));
1811
+ u(this, "raw");
1812
+ u(this, "delegatePolicy", "auto");
1813
+ u(this, "delegate", "GPU");
1814
+ /** Kept so the graph can be rebuilt on another delegate without refetching. */
1815
+ u(this, "vision", null);
1816
+ u(this, "modelBuffer", null);
1817
+ u(this, "graphOptions", {});
1818
+ u(this, "rebuilding", !1);
1819
+ u(this, "fallbackAttempted", !1);
1820
+ u(this, "result", Qs());
1821
+ u(this, "builder", new Zs());
1822
+ u(this, "node");
1823
+ this.node = {
1824
+ getResult: () => this.result,
1825
+ getRawResult: () => this.raw,
1826
+ getStatus: () => this.status,
1827
+ getError: () => this.error,
1828
+ getDelegate: () => this.delegate,
1829
+ setOptions: (t) => this.setRuntimeOptions(t)
1830
+ };
1831
+ }
1832
+ setRuntimeOptions(t) {
1833
+ const n = this.builder.getOptions().analysisMaxDimension;
1834
+ this.builder.setOptions(t);
1835
+ const i = this.builder.getOptions().analysisMaxDimension;
1836
+ i !== n && (this.downscaler.dispose(), this.downscaler = new we(i), this.downscaler.setScale(this.analysisScale));
1837
+ }
1838
+ async initialize(t) {
1839
+ this.status = "loading", this.error = null, this.setRuntimeOptions(t ?? {});
1840
+ try {
1841
+ const n = await $.forVisionTasks(
1842
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
1843
+ ), [i] = await Promise.all([
1844
+ ee((t == null ? void 0 : t.modelUrl) ?? Nt),
1845
+ te(n)
1846
+ ]);
1847
+ this.vision = n, this.modelBuffer = i, this.graphOptions = {
1848
+ runningMode: "VIDEO",
1849
+ outputFaceBlendshapes: (t == null ? void 0 : t.outputFaceBlendshapes) ?? !0,
1850
+ minFaceDetectionConfidence: t == null ? void 0 : t.minFaceDetectionConfidence,
1851
+ minFacePresenceConfidence: t == null ? void 0 : t.minFacePresenceConfidence,
1852
+ minPoseDetectionConfidence: t == null ? void 0 : t.minPoseDetectionConfidence,
1853
+ minPosePresenceConfidence: t == null ? void 0 : t.minPosePresenceConfidence,
1854
+ minHandLandmarksConfidence: t == null ? void 0 : t.minHandLandmarksConfidence
1855
+ }, this.delegatePolicy = (t == null ? void 0 : t.delegate) ?? "auto", this.delegate = this.delegatePolicy === "CPU" ? "CPU" : "GPU";
1856
+ const r = await this.createLandmarker(this.delegate);
1857
+ if (this.disposed) {
1858
+ r.close();
1859
+ return;
1860
+ }
1861
+ this.landmarker = r, this.status = "ready";
1862
+ } catch (n) {
1863
+ throw this.status = "error", this.error = n instanceof Error ? n : new Error(String(n)), this.error;
1864
+ }
1865
+ }
1866
+ createLandmarker(t) {
1867
+ if (!this.vision || !this.modelBuffer)
1868
+ throw new Error("HolisticTrackingModel: initialize() has not loaded the model");
1869
+ return Ns.createFromOptions(this.vision, {
1870
+ baseOptions: { modelAssetBuffer: this.modelBuffer, delegate: t },
1871
+ ...this.graphOptions
1872
+ });
1873
+ }
1874
+ /**
1875
+ * The GPU graph can fail on its first run (the face-blendshape stage has no
1876
+ * WebGL kernel for one of its ops). Rebuild on the CPU once, keep the RAF
1877
+ * loop alive meanwhile, and run one detection right away so static sources
1878
+ * (which pulse models once) still get a result.
1879
+ */
1880
+ async fallbackToCpu(t) {
1881
+ this.fallbackAttempted = !0, this.rebuilding = !0, this.status = "loading", console.warn(
1882
+ "[xr-sdk holistic] GPU inference failed; rebuilding the graph on the CPU delegate.",
1883
+ t.message
1884
+ );
1885
+ const n = this.landmarker;
1886
+ try {
1887
+ const i = await this.createLandmarker("CPU");
1888
+ if (this.disposed) {
1889
+ i.close();
1890
+ return;
1891
+ }
1892
+ this.landmarker = i, this.delegate = "CPU", this.status = "ready", this.error = null;
1893
+ try {
1894
+ n == null || n.close();
1895
+ } catch {
1896
+ }
1897
+ this.rebuilding = !1, this.detectOnce();
1898
+ } catch (i) {
1899
+ this.rebuilding = !1, this.status = "error", this.error = i instanceof Error ? i : new Error(String(i));
1900
+ }
1901
+ }
1902
+ /** One detect + publish outside the loop (used after a delegate rebuild). */
1903
+ detectOnce() {
1904
+ this.disposed || !this.landmarker || !this.sourceCanvas || (this.detect(), this.builder.update(this.raw, performance.now(), this.result, this.isMirrored()));
1905
+ }
1906
+ detect() {
1907
+ var i, r, o, a, d;
1908
+ if (!this.landmarker || !this.sourceCanvas) return;
1909
+ const t = this.downscaler.draw(this.sourceCanvas), n = performance.now();
1910
+ try {
1911
+ this.raw = this.landmarker.detectForVideo(t, n), this.status === "error" && (this.status = "ready", this.error = null), this.recordInferenceError(null);
1912
+ const l = this.raw, h = ((i = l.faceLandmarks) != null && i.length ? 1 : 0) + ((r = l.leftHandLandmarks) != null && r.length ? 1 : 0) + ((o = l.rightHandLandmarks) != null && o.length ? 1 : 0) + ((a = l.poseLandmarks) != null && a.length ? 1 : 0), m = (d = l.poseLandmarks) == null ? void 0 : d[0];
1913
+ this.recordDetections(
1914
+ h,
1915
+ m && m.length ? m.reduce((w, M) => w + (M.visibility ?? 0), 0) / m.length : null
1916
+ );
1917
+ } catch (l) {
1918
+ const h = l instanceof Error ? l : new Error(String(l));
1919
+ this.delegatePolicy === "auto" && this.delegate === "GPU" && !this.fallbackAttempted ? this.fallbackToCpu(h) : (this.status = "error", this.error = h, this.recordInferenceError(h));
1920
+ }
1921
+ this.processingTime = performance.now() - n, this.recordInference(n);
1922
+ }
1923
+ /** The session mirrors only the webcam feed (an unknown kind is treated as webcam). */
1924
+ isMirrored() {
1925
+ var t;
1926
+ return Se((t = this.getSource) == null ? void 0 : t.call(this));
1927
+ }
1928
+ async run({
1929
+ sourceCanvas: t,
1930
+ getSource: n,
1931
+ targetFps: i,
1932
+ analysisScale: r
1933
+ }) {
1934
+ this.sourceCanvas = t, this.getSource = n, this.setTargetFps(i), this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.rafId === null && await this.process();
1935
+ }
1936
+ async process() {
1937
+ this.disposed || this.paused || !this.landmarker || (!this.rebuilding && this.shouldRunInference() && this.detect(), this.builder.update(this.raw, performance.now(), this.result, this.isMirrored()), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.process.bind(this))));
1938
+ }
1939
+ resume() {
1940
+ this.paused && (super.resume(), this.process());
1941
+ }
1942
+ dispose() {
1943
+ if (super.dispose(), this.landmarker) {
1944
+ try {
1945
+ this.landmarker.close();
1946
+ } catch {
1947
+ }
1948
+ this.landmarker = null;
1949
+ }
1950
+ this.sourceCanvas = void 0, this.getSource = void 0, this.downscaler.dispose(), this.vision = null, this.modelBuffer = null, this.raw = void 0, this.builder.reset(), this.result.face = null, this.result.leftHand = null, this.result.rightHand = null, this.result.pose = null;
1951
+ }
1952
+ getModelNode() {
1953
+ return this.node;
1954
+ }
1955
+ async getPerformanceData() {
1956
+ return { name: this.constructor.name, processingTime: this.processingTime };
1957
+ }
1958
+ }
1959
+ const ni = (e) => e === "left" ? "right" : "left", ii = (e, s) => s ? ni(e) : e, ri = /left|right|Left|Right/, ai = {
1960
+ left: "right",
1961
+ right: "left",
1962
+ Left: "Right",
1963
+ Right: "Left"
1964
+ }, oi = (e) => e.replace(ri, (s) => ai[s]), Wr = (e, s) => s ? oi(e) : e, qr = (e) => e ? -1 : 1, ci = [
1965
+ "wrist",
1966
+ "thumbCmc",
1967
+ "thumbMcp",
1968
+ "thumbIp",
1969
+ "thumbTip",
1970
+ "indexMcp",
1971
+ "indexPip",
1972
+ "indexDip",
1973
+ "indexTip",
1974
+ "middleMcp",
1975
+ "middlePip",
1976
+ "middleDip",
1977
+ "middleTip",
1978
+ "ringMcp",
1979
+ "ringPip",
1980
+ "ringDip",
1981
+ "ringTip",
1982
+ "pinkyMcp",
1983
+ "pinkyPip",
1984
+ "pinkyDip",
1985
+ "pinkyTip"
1986
+ ], Vr = Object.fromEntries(
1987
+ ci.map((e, s) => [e, s])
1988
+ ), li = 200, fe = (e, s) => Math.hypot(e.x - s.x, e.y - s.y), ge = (e) => e === "left" ? "right" : "left", Ge = (e, s, t) => ({
1989
+ handedness: s,
1990
+ score: e.score,
1991
+ world: e.world,
1992
+ image: e.image,
1993
+ timestampMs: t,
1994
+ held: !1
1995
+ }), di = (e, s, t, {
1996
+ holdMs: n = li,
1997
+ confidentScore: i = 0.8,
1998
+ continuityMs: r = 500
1999
+ } = {}) => {
2000
+ const o = (l) => !!l && t - l.timestampMs <= r && l.image.length > 0, a = { left: null, right: null }, d = e.filter((l) => l.image.length > 0).slice(0, 2);
2001
+ if (d.length === 2) {
2002
+ const [l, h] = d, m = l.handedness !== void 0 && h.handedness !== void 0 && l.handedness !== h.handedness, w = l.score >= i && h.score >= i;
2003
+ let M;
2004
+ if (m && w)
2005
+ M = l.handedness;
2006
+ else if (o(s.left) && o(s.right)) {
2007
+ const x = fe(l.image[0], s.left.image[0]) + fe(h.image[0], s.right.image[0]), b = fe(l.image[0], s.right.image[0]) + fe(h.image[0], s.left.image[0]);
2008
+ M = x <= b ? "left" : "right";
2009
+ } else if (m)
2010
+ M = l.handedness;
2011
+ else {
2012
+ const x = l.score >= h.score ? l : h, b = x.handedness ?? "right";
2013
+ M = x === l ? b : ge(b);
2014
+ }
2015
+ a[M] = Ge(l, M, t), a[ge(M)] = Ge(h, ge(M), t);
2016
+ } else if (d.length === 1) {
2017
+ const [l] = d;
2018
+ let h = l.handedness ?? "right";
2019
+ if (l.score < i || l.handedness === void 0) {
2020
+ const m = (x) => o(x) ? fe(l.image[0], x.image[0]) : 1 / 0, w = m(s[h]);
2021
+ m(s[ge(h)]) < w && (h = ge(h));
2022
+ }
2023
+ a[h] = Ge(l, h, t);
2024
+ }
2025
+ for (const l of ["left", "right"]) {
2026
+ const h = s[l];
2027
+ a[l] || !h || t - h.timestampMs <= n && (a[l] = { ...h, held: !0 });
2028
+ }
2029
+ return a;
2030
+ }, hi = (e, s) => {
2031
+ const t = e == null ? void 0 : e.toLowerCase();
2032
+ if (!(t !== "left" && t !== "right"))
2033
+ return ii(t, s);
2034
+ }, ui = (e, s = { x: 0, y: 0, z: 0 }) => (s.x = e.x * 100, s.y = -e.y * 100, s.z = -e.z * 100, s), mi = 512, fi = Object.freeze({
2035
+ minHandDetectionConfidence: 0.5,
2036
+ minHandPresenceConfidence: 0.65,
2037
+ minTrackingConfidence: 0.5
2038
+ });
2039
+ class gi extends se {
2040
+ constructor() {
2041
+ super();
2042
+ u(this, "landmarker", null);
2043
+ u(this, "processingTime", null);
2044
+ u(this, "hands");
2045
+ u(this, "coordinates");
2046
+ u(this, "gesture");
2047
+ u(this, "handedness");
2048
+ u(this, "poses", { left: null, right: null });
2049
+ u(this, "sourceCanvas");
2050
+ u(this, "getSource");
2051
+ u(this, "downscaler", new we(mi));
2052
+ }
2053
+ async getHandData() {
2054
+ var m, w, M;
2055
+ if (!this.landmarker || !this.sourceCanvas)
2056
+ return;
2057
+ const t = this.downscaler.draw(this.sourceCanvas), n = performance.now(), i = this.landmarker.detectForVideo(t, n), r = performance.now();
2058
+ this.processingTime = r - n, this.recordInference(n, r);
2059
+ const o = [], a = [], d = i.handedness ?? i.handednesses ?? [];
2060
+ this.recordDetections(i.landmarks.length, ((w = (m = d[0]) == null ? void 0 : m[0]) == null ? void 0 : w.score) ?? null);
2061
+ const l = Se((M = this.getSource) == null ? void 0 : M.call(this));
2062
+ if (i.landmarks.forEach((x, b) => {
2063
+ var A, E;
2064
+ if (!x || x.length === 0)
2065
+ return;
2066
+ const T = x.map(
2067
+ (B) => ue(B)
2068
+ ), R = (((A = i.worldLandmarks) == null ? void 0 : A[b]) ?? []).map(
2069
+ (B) => ui(B)
2070
+ ), y = (E = d[b]) == null ? void 0 : E[0], g = hi(y == null ? void 0 : y.categoryName, l), p = (y == null ? void 0 : y.score) ?? 0, v = x[0].z < 0 ? "closed_fist" : "open_palm";
2071
+ o.push({ coordinates: T, worldCoordinates: R, gesture: v, handedness: g, handednessScore: p }), a.push({
2072
+ handedness: g,
2073
+ score: p,
2074
+ world: R,
2075
+ image: T
2076
+ });
2077
+ }), this.poses = di(a, this.poses, n), !o.length)
2078
+ return {
2079
+ hands: void 0,
2080
+ coordinates: void 0,
2081
+ gesture: void 0,
2082
+ handedness: void 0
2083
+ };
2084
+ const h = o[0];
2085
+ return {
2086
+ hands: o,
2087
+ coordinates: h.coordinates,
2088
+ gesture: h.gesture,
2089
+ handedness: h.handedness
2090
+ };
2091
+ }
2092
+ async processHandTracking() {
2093
+ if (!this.disposed) {
2094
+ if (this.shouldRunInference()) {
2095
+ const t = await this.getHandData();
2096
+ t && (this.hands = t.hands, this.coordinates = t.coordinates, this.gesture = t.gesture, this.handedness = t.handedness);
2097
+ }
2098
+ this.disposed || this.paused || (this.rafId = requestAnimationFrame(this.processHandTracking.bind(this)));
2099
+ }
2100
+ }
2101
+ resume() {
2102
+ this.paused && (super.resume(), this.processHandTracking());
2103
+ }
2104
+ dispose() {
2105
+ if (super.dispose(), this.landmarker) {
2106
+ try {
2107
+ this.landmarker.close();
2108
+ } catch {
2109
+ }
2110
+ this.landmarker = null;
2111
+ }
2112
+ this.sourceCanvas = void 0, this.getSource = void 0, this.hands = void 0, this.poses = { left: null, right: null }, this.downscaler.dispose(), this.coordinates = void 0, this.gesture = void 0, this.handedness = void 0;
2113
+ }
2114
+ async initialize() {
2115
+ const t = await $.forVisionTasks(
2116
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
2117
+ ), [n] = await Promise.all([
2118
+ ee(
2119
+ new URL("/assets/xr/models/hand_tracking.task", W.assetStorageEndpoint).toString()
2120
+ ),
2121
+ te(t)
2122
+ ]), i = await Bs.createFromOptions(t, {
2123
+ baseOptions: {
2124
+ modelAssetBuffer: n,
2125
+ delegate: "GPU"
2126
+ },
2127
+ runningMode: "VIDEO",
2128
+ numHands: 2,
2129
+ ...fi
2130
+ });
2131
+ this.landmarker = i;
2132
+ }
2133
+ async run({
2134
+ sourceCanvas: t,
2135
+ getSource: n,
2136
+ targetFps: i,
2137
+ analysisScale: r
2138
+ }) {
2139
+ this.getSource = n, this.setAnalysisScale(r), this.downscaler.setScale(this.analysisScale), this.sourceCanvas = t, this.setTargetFps(i), this.rafId === null && await this.processHandTracking();
2140
+ }
2141
+ getModelNode() {
2142
+ const t = this;
2143
+ return {
2144
+ get hands() {
2145
+ return t.hands;
2146
+ },
2147
+ get coordinates() {
2148
+ return t.coordinates;
2149
+ },
2150
+ get gesture() {
2151
+ return t.gesture;
2152
+ },
2153
+ get handedness() {
2154
+ return t.handedness;
2155
+ },
2156
+ get poses() {
2157
+ return t.poses;
2158
+ },
2159
+ getHandPose: (n) => t.poses[n]
2160
+ };
2161
+ }
2162
+ async getPerformanceData() {
2163
+ return {
2164
+ name: this.constructor.name,
2165
+ processingTime: this.processingTime
2166
+ };
2167
+ }
2168
+ }
2169
+ const pi = 24, yi = 720, wi = [
2170
+ [255, 255, 255, 255],
2171
+ // 0: the person → white
2172
+ [0, 0, 0, 0]
2173
+ // 1
2174
+ ];
2175
+ class vi extends se {
2176
+ constructor() {
2177
+ super();
2178
+ u(this, "segmenter", null);
2179
+ u(this, "processingTime", null);
2180
+ u(this, "sourceCanvas");
2181
+ // input source canvas
2182
+ u(this, "processCanvas");
2183
+ // downscaled canvas of sourceCanvas for processing
2184
+ u(this, "filterCanvas");
2185
+ // post-processing (blur) canvas
2186
+ // Optional high-resolution input override. The shared session feed canvas is
2187
+ // sized to the on-screen display layout (often a small, display-fit crop),
2188
+ // which starves the segmenter of the resolution it needs to capture the whole
2189
+ // body. When a consumer supplies a native-resolution source here (e.g. the raw
2190
+ // <video>/<img>), the segmenter runs on THAT instead — letterboxed into the
2191
+ // process canvas so nothing is cropped. Falls back to `sourceCanvas` when unset.
2192
+ u(this, "inputSource");
2193
+ u(this, "inputSourceSize");
2194
+ // The segmenter's own WebGL2 context. DrawingUtils renders the inverted mask
2195
+ // into this context on the GPU; we then blit that GL canvas straight into the
2196
+ // mask canvas with a single `drawImage` — a GPU→GPU transfer, no CPU readback
2197
+ // and no per-pixel JS loop. (A spike proved `drawImage(glCanvas)` reads the
2198
+ // full DrawingUtils output correctly; the earlier "reads empty" wall that once
2199
+ // forced a readPixels path was a false alarm.)
2200
+ u(this, "glCanvas");
2201
+ u(this, "drawingUtils");
2202
+ u(this, "useGpuMaskPath", !1);
2203
+ // CPU-fallback reused ImageData, allocated on size change only. Used ONLY when
2204
+ // WebGL2 is unavailable and we must read the single-channel mask back by hand.
2205
+ u(this, "maskImageData");
2206
+ u(this, "maskCanvas", null);
2207
+ u(this, "segmentationMaskTexture");
2208
+ u(this, "isMaskSetup", !1);
2209
+ u(this, "isProcessing", !1);
2210
+ // Live clone of the most recent category mask, kept so getRawSegmentationData()
2211
+ // can read the single-channel Uint8Array lazily — that readback is paid ONLY
2212
+ // when a consumer actually asks for raw data. Cloned because the mask returned
2213
+ // by segmentForVideo is invalidated on the next inference call.
2214
+ u(this, "latestMask", null);
2215
+ // Per-frame cache of the read-back array, so repeated getRawSegmentationData()
2216
+ // calls within one frame don't re-run the GPU→CPU transfer.
2217
+ u(this, "rawCache", null);
2218
+ /** When the frame behind `latestMask` was segmented (`performance.now()`). */
2219
+ u(this, "latestMaskTimeMs", 0);
2220
+ u(this, "quality", "medium");
2221
+ u(this, "stagingCanvas");
2222
+ }
2223
+ getQualityScaleFactor() {
2224
+ switch (this.quality) {
2225
+ case "low":
2226
+ return 0.5;
2227
+ case "medium":
2228
+ return 0.75;
2229
+ case "high":
2230
+ return 1;
2231
+ default:
2232
+ return 0.5;
2233
+ }
2234
+ }
2235
+ /**
2236
+ * Set (or clear) a high-resolution input override. Pass the raw <video>/<img>
2237
+ * (or any CanvasImageSource with intrinsic dimensions) to run segmentation on
2238
+ * native-resolution, uncropped frames instead of the small display-fit session
2239
+ * feed. Pass `undefined` to revert to the shared feed canvas.
2240
+ */
2241
+ setInputSource(t) {
2242
+ this.inputSource = t, this.inputSourceSize = t ? this.readIntrinsicSize(t) : void 0;
2243
+ }
2244
+ readIntrinsicSize(t) {
2245
+ if (t instanceof HTMLVideoElement)
2246
+ return t.videoWidth > 0 ? { width: t.videoWidth, height: t.videoHeight } : void 0;
2247
+ if (t instanceof HTMLImageElement)
2248
+ return t.naturalWidth > 0 ? { width: t.naturalWidth, height: t.naturalHeight } : void 0;
2249
+ const n = t.width, i = t.height;
2250
+ return typeof n == "number" && n > 0 && typeof i == "number" && i > 0 ? { width: n, height: i } : void 0;
2251
+ }
2252
+ /**
2253
+ * Size the process canvas to the override input's aspect ratio, bounded by
2254
+ * PROCESS_MAX_DIM on the long edge, and keep the GL canvas in sync so the GPU
2255
+ * mask renders at the same resolution. No-op when there is no override, or when
2256
+ * the intrinsic size hasn't changed since the last frame.
2257
+ */
2258
+ ensureProcessCanvasForInput() {
2259
+ if (!this.processCanvas || !this.inputSource) return;
2260
+ const t = this.readIntrinsicSize(this.inputSource);
2261
+ if (!t) return;
2262
+ this.inputSourceSize = t;
2263
+ const n = Math.min(1, yi / Math.max(t.width, t.height)), i = Math.max(1, Math.round(t.width * n)), r = Math.max(1, Math.round(t.height * n));
2264
+ this.processCanvas.width === i && this.processCanvas.height === r || (this.processCanvas.width = i, this.processCanvas.height = r, this.glCanvas && (this.glCanvas.width = i, this.glCanvas.height = r), this.maskImageData = void 0);
2265
+ }
2266
+ async processSegmentation() {
2267
+ if (this.disposed || !this.isProcessing || !this.maskCanvas || !this.processCanvas)
2268
+ return;
2269
+ if (!this.shouldRunInference()) {
2270
+ if (this.disposed || this.paused) return;
2271
+ this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
2272
+ return;
2273
+ }
2274
+ const t = this.inputSource ?? this.sourceCanvas;
2275
+ if (!this.segmenter || !t) {
2276
+ if (this.disposed || this.paused) return;
2277
+ this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
2278
+ return;
2279
+ }
2280
+ const n = performance.now();
2281
+ this.ensureProcessCanvasForInput();
2282
+ const i = this.processCanvas.getContext("2d");
2283
+ if (i) {
2284
+ const d = this.processCanvas.width, l = this.processCanvas.height;
2285
+ if (i.clearRect(0, 0, d, l), this.inputSource && this.inputSourceSize) {
2286
+ const { width: h, height: m } = this.inputSourceSize, w = Math.min(d / h, l / m), M = h * w, x = m * w;
2287
+ i.drawImage(this.inputSource, (d - M) / 2, (l - x) / 2, M, x);
2288
+ } else
2289
+ i.drawImage(t, 0, 0, d, l);
2290
+ }
2291
+ const r = performance.now(), a = this.segmenter.segmentForVideo(this.processCanvas, r).categoryMask;
2292
+ if (!a) {
2293
+ if (this.disposed || this.paused) return;
2294
+ this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
2295
+ return;
2296
+ }
2297
+ if (this.rawCache = null, this.latestMaskTimeMs = r, this.latestMask && (this.latestMask.close(), this.latestMask = null), this.useGpuMaskPath && this.drawingUtils && this.glCanvas)
2298
+ this.drawingUtils.drawCategoryMask(a, wi), this.latestMask = a.clone(), a.close(), this.blitGlToMask();
2299
+ else {
2300
+ this.latestMask = a.clone();
2301
+ const d = this.readMaskToImageData(a);
2302
+ a.close(), d && this.blitImageDataToMask(d);
2303
+ }
2304
+ this.segmentationMaskTexture && (this.isMaskSetup || (this.segmentationMaskTexture.format = Ot, this.segmentationMaskTexture.minFilter = Re, this.segmentationMaskTexture.magFilter = Re, this.segmentationMaskTexture.generateMipmaps = !1, this.isMaskSetup = !0), this.segmentationMaskTexture.needsUpdate = !0), this.processingTime = performance.now() - n, this.recordInference(n), this.recordDetections(1, null), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.processSegmentation.bind(this)));
2305
+ }
2306
+ /**
2307
+ * Blit the GPU-rendered mask (already RGBA-inverted by drawCategoryMask)
2308
+ * straight from the GL canvas into the mask canvas, cover-fitted through the
2309
+ * soft-edge blur. `drawImage(glCanvas)` is a GPU→GPU transfer — no readPixels,
2310
+ * no CPU array, no ImageData, no row flip (the 2D canvas presents the WebGL
2311
+ * canvas right-side-up). This is the zero-readback path.
2312
+ */
2313
+ blitGlToMask() {
2314
+ if (!this.maskCanvas || !this.filterCanvas || !this.glCanvas) return;
2315
+ const t = this.maskCanvas.getContext("2d"), n = this.filterCanvas.getContext("2d");
2316
+ !t || !n || (n.filter = "blur(0.5px)", n.clearRect(0, 0, this.filterCanvas.width, this.filterCanvas.height), n.drawImage(this.glCanvas, 0, 0, this.filterCanvas.width, this.filterCanvas.height), t.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height), t.drawImage(this.filterCanvas, 0, 0, this.maskCanvas.width, this.maskCanvas.height));
2317
+ }
2318
+ /**
2319
+ * CPU-fallback ImageData build (only when the GPU path is off). The
2320
+ * single-channel mask is expanded to RGBA with green and alpha 255 on the
2321
+ * person and 0 on the background, like the GPU path (green carries the
2322
+ * signal for the alphaMap).
2323
+ */
2324
+ readMaskToImageData(t) {
2325
+ const n = t.getAsUint8Array(), { width: i, height: r } = t;
2326
+ if (!n || i <= 0 || r <= 0) return null;
2327
+ (!this.maskImageData || this.maskImageData.width !== i || this.maskImageData.height !== r) && (this.maskImageData = new ImageData(i, r));
2328
+ const o = this.maskImageData.data;
2329
+ for (let a = 0; a < n.length; a += 1) {
2330
+ const d = n[a] === 255 ? 0 : 255;
2331
+ o[a * 4] = 255, o[a * 4 + 1] = d, o[a * 4 + 2] = 255, o[a * 4 + 3] = d;
2332
+ }
2333
+ return this.maskImageData;
2334
+ }
2335
+ /**
2336
+ * CPU-fallback blit: put the inverted-alpha mask ImageData into maskCanvas
2337
+ * with a soft-edge blur, cover-fitted to the render target. Only used when the
2338
+ * GPU path is off; the GPU path blits the GL canvas directly (blitGlToMask).
2339
+ */
2340
+ blitImageDataToMask(t) {
2341
+ if (!this.maskCanvas || !this.filterCanvas) return;
2342
+ const n = this.maskCanvas.getContext("2d"), i = this.filterCanvas.getContext("2d");
2343
+ if (!n || !i) return;
2344
+ const r = this.getStagingCanvas(t.width, t.height), o = r.getContext("2d");
2345
+ o && (o.putImageData(t, 0, 0), i.filter = "blur(0.5px)", i.clearRect(0, 0, this.filterCanvas.width, this.filterCanvas.height), i.drawImage(r, 0, 0, this.filterCanvas.width, this.filterCanvas.height), n.clearRect(0, 0, this.maskCanvas.width, this.maskCanvas.height), n.drawImage(this.filterCanvas, 0, 0, this.maskCanvas.width, this.maskCanvas.height));
2346
+ }
2347
+ getStagingCanvas(t, n) {
2348
+ return this.stagingCanvas || (this.stagingCanvas = document.createElement("canvas")), this.stagingCanvas.width !== t && (this.stagingCanvas.width = t), this.stagingCanvas.height !== n && (this.stagingCanvas.height = n), this.stagingCanvas;
2349
+ }
2350
+ resume() {
2351
+ this.paused && (super.resume(), this.processSegmentation());
2352
+ }
2353
+ dispose() {
2354
+ if (super.dispose(), this.isProcessing = !1, this.latestMask) {
2355
+ try {
2356
+ this.latestMask.close();
2357
+ } catch {
2358
+ }
2359
+ this.latestMask = null;
2360
+ }
2361
+ if (this.rawCache = null, this.segmenter) {
2362
+ try {
2363
+ this.segmenter.close();
2364
+ } catch {
2365
+ }
2366
+ this.segmenter = null;
2367
+ }
2368
+ this.drawingUtils = void 0, this.glCanvas = void 0, this.maskImageData = void 0, this.segmentationMaskTexture && (this.segmentationMaskTexture.dispose(), this.segmentationMaskTexture = void 0), this.sourceCanvas = void 0, this.inputSource = void 0, this.inputSourceSize = void 0, this.processCanvas = void 0, this.filterCanvas = void 0, this.stagingCanvas = void 0, this.maskCanvas = null;
2369
+ }
2370
+ async initialize(t) {
2371
+ this.quality = (t == null ? void 0 : t.quality) ?? "low";
2372
+ const n = await $.forVisionTasks(
2373
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
2374
+ ), [i] = await Promise.all([
2375
+ ee(
2376
+ new URL("/assets/xr/models/segmentation.tflite", W.assetStorageEndpoint).toString()
2377
+ ),
2378
+ te(n)
2379
+ ]);
2380
+ this.glCanvas = new OffscreenCanvas(1, 1);
2381
+ const r = this.glCanvas.getContext("webgl2", {
2382
+ preserveDrawingBuffer: !0
2383
+ });
2384
+ this.segmenter = await Dt.createFromOptions(n, {
2385
+ baseOptions: {
2386
+ modelAssetBuffer: i,
2387
+ delegate: "GPU"
2388
+ },
2389
+ ...r ? { canvas: this.glCanvas } : {},
2390
+ outputCategoryMask: !0,
2391
+ outputConfidenceMasks: !1,
2392
+ runningMode: "VIDEO"
2393
+ }), r ? (this.drawingUtils = new Hs(r), this.useGpuMaskPath = !0) : this.useGpuMaskPath = !1;
2394
+ }
2395
+ async run({
2396
+ sourceCanvas: t,
2397
+ renderWidth: n,
2398
+ renderHeight: i,
2399
+ targetFps: r
2400
+ }) {
2401
+ var a;
2402
+ if (!t)
2403
+ return;
2404
+ this.setTargetFps(r ?? pi), this.isProcessing = !1, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null);
2405
+ const o = this.getQualityScaleFactor();
2406
+ this.sourceCanvas = t, this.processCanvas = document.createElement("canvas"), this.processCanvas.width = t.width * o, this.processCanvas.height = t.height * o, this.glCanvas && (this.glCanvas.width = this.processCanvas.width, this.glCanvas.height = this.processCanvas.height), this.maskImageData = void 0, this.maskCanvas = document.createElement("canvas"), this.maskCanvas.width = n, this.maskCanvas.height = i, this.filterCanvas = document.createElement("canvas"), this.filterCanvas.width = n, this.filterCanvas.height = i, (a = this.segmentationMaskTexture) == null || a.dispose(), this.segmentationMaskTexture = new Lt(this.maskCanvas), this.isMaskSetup = !1, this.rawCache = null, this.isProcessing = !0, this.lastInferenceMs = 0, this.rafId = requestAnimationFrame(this.processSegmentation.bind(this));
2407
+ }
2408
+ /**
2409
+ * Lazily read the single-channel mask back to a Uint8Array. Only invoked when
2410
+ * a consumer calls getRawSegmentationData(); the default texture path never
2411
+ * touches it, so apps that only use <VideoBackground> pay no extra readback.
2412
+ */
2413
+ getRawSegmentationData() {
2414
+ if (this.rawCache) return this.rawCache;
2415
+ if (!this.latestMask) return null;
2416
+ const t = this.latestMask.getAsUint8Array();
2417
+ return this.rawCache = {
2418
+ maskData: t,
2419
+ width: this.latestMask.width,
2420
+ height: this.latestMask.height,
2421
+ timestampMs: this.latestMaskTimeMs
2422
+ }, this.rawCache;
2423
+ }
2424
+ getModelNode() {
2425
+ const t = this;
2426
+ return {
2427
+ get backgroundSegmentationMask() {
2428
+ return t.segmentationMaskTexture;
2429
+ },
2430
+ getMaskCanvas: () => t.maskCanvas,
2431
+ getRawSegmentationData: () => t.getRawSegmentationData(),
2432
+ getMaskTimestampMs: () => t.latestMaskTimeMs,
2433
+ setInputSource: (n) => t.setInputSource(n ?? void 0)
2434
+ };
2435
+ }
2436
+ async getPerformanceData() {
2437
+ return {
2438
+ name: this.constructor.name,
2439
+ processingTime: this.processingTime
2440
+ };
2441
+ }
2442
+ }
2443
+ const xi = (e, s, t, n = "feed") => ({
2444
+ width: Math.max(1, Math.round(e)),
2445
+ height: Math.max(1, Math.round(s)),
2446
+ indices: new Uint8Array(Math.max(1, Math.round(e)) * Math.max(1, Math.round(s))),
2447
+ labels: t,
2448
+ space: n,
2449
+ version: 0
2450
+ }), Kr = (e) => {
2451
+ e.indices.fill(0);
2452
+ }, Gr = (e, s) => e.labels.indexOf(s), Si = (e, s, t) => {
2453
+ const { width: n, height: i, indices: r } = e, o = s.length;
2454
+ if (o < 3) return;
2455
+ let a = 1 / 0, d = -1 / 0;
2456
+ for (let w = 0; w < o; w += 1) {
2457
+ const M = s[w].y * i;
2458
+ M < a && (a = M), M > d && (d = M);
2459
+ }
2460
+ const l = Math.max(0, Math.floor(a)), h = Math.min(i - 1, Math.ceil(d)), m = [];
2461
+ for (let w = l; w <= h; w += 1) {
2462
+ const M = w + 0.5;
2463
+ m.length = 0;
2464
+ for (let b = 0; b < o; b += 1) {
2465
+ const T = s[b], R = s[(b + 1) % o], y = T.y * i, g = R.y * i;
2466
+ if (M < y == M < g) continue;
2467
+ const p = (M - y) / (g - y);
2468
+ m.push((T.x + p * (R.x - T.x)) * n);
2469
+ }
2470
+ m.sort((b, T) => b - T);
2471
+ const x = w * n;
2472
+ for (let b = 0; b + 1 < m.length; b += 2) {
2473
+ const T = Math.max(0, Math.round(m[b])), R = Math.min(n, Math.round(m[b + 1]));
2474
+ for (let y = T; y < R; y += 1) r[x + y] = t;
2475
+ }
2476
+ }
2477
+ }, Xr = (e, s, t, n, i = []) => {
2478
+ i.length = 0;
2479
+ for (let r = 0; r < t.length; r += 1) {
2480
+ const o = s[t[r]];
2481
+ if (!o) return;
2482
+ i.push(o);
2483
+ }
2484
+ Si(e, i, n);
2485
+ }, Xe = (e) => e, At = {
2486
+ hair: {
2487
+ labels: ["bg", "hair"],
2488
+ assetPath: "/assets/xr/models/hair_segmenter.tflite",
2489
+ defaultUrl: "https://storage.googleapis.com/mediapipe-models/image_segmenter/hair_segmenter/float32/latest/hair_segmenter.tflite",
2490
+ decode: Xe
2491
+ },
2492
+ multiclass: {
2493
+ labels: ["bg", "hair", "body_skin", "face_skin", "clothes", "others"],
2494
+ assetPath: "/assets/xr/models/selfie_multiclass_256x256.tflite",
2495
+ defaultUrl: "https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_multiclass_256x256/float32/latest/selfie_multiclass_256x256.tflite",
2496
+ decode: Xe
2497
+ },
2498
+ // Fingernails: the MIT-licensed tiny U-Net from nngeek195/nail-segmentation-v1
2499
+ // (Hugging Face), re-exported to TFLite float16 with the input normalisation
2500
+ // baked in (0..1 RGB, as MediaPipe feeds it) and a two-class output
2501
+ // (assets-src/nail-segmenter). Fixed input
2502
+ // 128 × 224 (w × h): MediaPipe stretches the feed to it.
2503
+ nails: {
2504
+ labels: ["bg", "nail"],
2505
+ assetPath: "/assets/xr/models/nail_segmenter_v1.tflite",
2506
+ defaultUrl: "https://cdn.vincentt.studio/assets/xr/models/nail_segmenter_v1.tflite",
2507
+ decode: Xe
2508
+ }
2509
+ }, Mi = (e, s, t) => {
2510
+ const n = t.length === e.length ? t : new Uint8Array(e.length);
2511
+ for (let i = 0; i < e.length; i += 1) n[i] = s(e[i]);
2512
+ return n;
2513
+ }, bi = 15, ki = { low: 0.5, medium: 0.75, high: 1 };
2514
+ class Ci extends se {
2515
+ constructor() {
2516
+ super();
2517
+ u(this, "segmenter", null);
2518
+ u(this, "preset", "hair");
2519
+ u(this, "quality", "medium");
2520
+ u(this, "status", "loading");
2521
+ u(this, "error", null);
2522
+ u(this, "processingTime", null);
2523
+ u(this, "sourceCanvas");
2524
+ u(this, "processCanvas");
2525
+ u(this, "isProcessing", !1);
2526
+ u(this, "mask", xi(1, 1, ["bg"]));
2527
+ u(this, "node");
2528
+ this.node = {
2529
+ getMask: () => this.mask,
2530
+ getStatus: () => this.status,
2531
+ getError: () => this.error
2532
+ };
2533
+ }
2534
+ async initialize(t) {
2535
+ this.preset = (t == null ? void 0 : t.preset) ?? "hair", this.quality = (t == null ? void 0 : t.quality) ?? "medium";
2536
+ const n = At[this.preset];
2537
+ this.mask.labels = n.labels, this.status = "loading", this.error = null;
2538
+ try {
2539
+ const i = await $.forVisionTasks(
2540
+ new URL("/assets/xr/wasm", W.assetStorageEndpoint).toString()
2541
+ ), r = (t == null ? void 0 : t.modelUrl) ?? n.defaultUrl, [o] = await Promise.all([
2542
+ ee(r),
2543
+ te(i)
2544
+ ]);
2545
+ this.segmenter = await Dt.createFromOptions(i, {
2546
+ baseOptions: { modelAssetBuffer: o, delegate: "GPU" },
2547
+ outputCategoryMask: !0,
2548
+ outputConfidenceMasks: !1,
2549
+ runningMode: "VIDEO"
2550
+ }), this.status = "ready";
2551
+ } catch (i) {
2552
+ throw this.status = "error", this.error = i instanceof Error ? i : new Error(String(i)), this.error;
2553
+ }
2554
+ }
2555
+ async run({ sourceCanvas: t, targetFps: n }) {
2556
+ t && (this.setTargetFps(n ?? bi), this.isProcessing = !1, this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null), this.sourceCanvas = t, this.processCanvas = document.createElement("canvas"), this.isProcessing = !0, this.lastInferenceMs = 0, this.rafId = requestAnimationFrame(this.process.bind(this)));
2557
+ }
2558
+ process() {
2559
+ if (this.disposed || this.paused || !this.isProcessing) return;
2560
+ const { segmenter: t, sourceCanvas: n, processCanvas: i } = this;
2561
+ if (!t || !n || !i || !this.shouldRunInference()) {
2562
+ this.rafId = requestAnimationFrame(this.process.bind(this));
2563
+ return;
2564
+ }
2565
+ const r = performance.now(), o = ki[this.quality], a = Math.max(1, Math.round(n.width * o)), d = Math.max(1, Math.round(n.height * o));
2566
+ (i.width !== a || i.height !== d) && (i.width = a, i.height = d);
2567
+ const l = i.getContext("2d");
2568
+ l && l.drawImage(n, 0, 0, a, d);
2569
+ try {
2570
+ const m = t.segmentForVideo(i, performance.now()).categoryMask;
2571
+ if (m) {
2572
+ const w = m.getAsUint8Array();
2573
+ (this.mask.width !== m.width || this.mask.height !== m.height) && (this.mask.width = m.width, this.mask.height = m.height), this.mask.indices = Mi(
2574
+ w,
2575
+ At[this.preset].decode,
2576
+ this.mask.indices
2577
+ ), this.mask.version += 1, this.mask.timestampMs = r, m.close();
2578
+ }
2579
+ this.status === "error" && (this.status = "ready", this.error = null), this.recordInferenceError(null), this.recordDetections(m ? 1 : 0, null);
2580
+ } catch (h) {
2581
+ this.status = "error", this.error = h instanceof Error ? h : new Error(String(h)), this.recordInferenceError(this.error);
2582
+ }
2583
+ this.processingTime = performance.now() - r, this.recordInference(r), !(this.disposed || this.paused) && (this.rafId = requestAnimationFrame(this.process.bind(this)));
2584
+ }
2585
+ resume() {
2586
+ this.paused && (super.resume(), this.isProcessing && (this.rafId = requestAnimationFrame(this.process.bind(this))));
2587
+ }
2588
+ getModelNode() {
2589
+ return this.node;
2590
+ }
2591
+ async getPerformanceData() {
2592
+ return { name: this.constructor.name, processingTime: this.processingTime };
2593
+ }
2594
+ dispose() {
2595
+ var t;
2596
+ super.dispose(), this.isProcessing = !1;
2597
+ try {
2598
+ (t = this.segmenter) == null || t.close();
2599
+ } catch {
2600
+ }
2601
+ this.segmenter = null, this.sourceCanvas = void 0, this.processCanvas = void 0;
2602
+ }
2603
+ }
2604
+ const It = {
2605
+ [F.BACKGROUND_SEGMENTATION]: vi,
2606
+ [F.SEMANTIC_SEGMENTATION]: Ci,
2607
+ [F.HAND_TRACKER]: gi,
2608
+ [F.GESTURE_TRACKER]: ti,
2609
+ [F.FACE_TRACKER]: Qn,
2610
+ [F.BODY_TRACKER]: qn,
2611
+ [F.HOLISTIC_TRACKER]: si
2612
+ }, Ti = async (e) => {
2613
+ const s = document.createElement("video");
2614
+ s.srcObject = e, s.muted = !0, s.playsInline = !0, s.autoplay = !0, await new Promise((n) => {
2615
+ s.onloadedmetadata = () => {
2616
+ s.play(), n();
2617
+ };
2618
+ });
2619
+ const t = s;
2620
+ return await new Promise((n) => {
2621
+ const i = setTimeout(n, 150), r = () => {
2622
+ clearTimeout(i), n();
2623
+ };
2624
+ typeof t.requestVideoFrameCallback == "function" ? t.requestVideoFrameCallback(r) : requestAnimationFrame(() => requestAnimationFrame(() => r()));
2625
+ }), s;
2626
+ }, Ei = (e) => {
2627
+ const s = new Lt(e);
2628
+ return s.colorSpace = Vs, s.format = Ot, s.minFilter = Re, s.magFilter = Re, s.generateMipmaps = !1, s.needsUpdate = !0, s;
2629
+ }, Ri = (e, s) => {
2630
+ const t = e.videoWidth, n = e.videoHeight;
2631
+ t > 0 && n > 0 && (s.width !== t && (s.width = t), s.height !== n && (s.height = n));
2632
+ const i = s.getContext("2d", {
2633
+ colorSpace: "srgb"
2634
+ });
2635
+ i.save(), i.scale(-1, 1), i.drawImage(e, -s.width, 0, s.width, s.height), i.restore();
2636
+ }, Ai = (e, s, t = 1) => {
2637
+ const n = s.getContext("2d", {
2638
+ colorSpace: "srgb"
2639
+ }), i = un({
2640
+ source: { width: e.width, height: e.height },
2641
+ feed: { width: s.width, height: s.height },
2642
+ zoom: t
2643
+ });
2644
+ i && (n.setTransform(1, 0, 0, 1, 0, 0), n.clearRect(0, 0, s.width, s.height), n.drawImage(
2645
+ e,
2646
+ 0,
2647
+ 0,
2648
+ e.width,
2649
+ e.height,
2650
+ i.offsetX,
2651
+ i.offsetY,
2652
+ i.drawWidth,
2653
+ i.drawHeight
2654
+ ));
2655
+ }, Ii = (e, s, t) => {
2656
+ const n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new WeakSet();
2657
+ let r = !1;
2658
+ const o = (y, g) => {
2659
+ const p = e.getSnapshot().modelErrors;
2660
+ if (g === null && !p.has(y)) return;
2661
+ const v = new Map(p);
2662
+ g === null ? v.delete(y) : v.set(y, { model: y, error: g, at: performance.now() }), e.set({ modelErrors: v });
2663
+ }, a = (y, g) => {
2664
+ var p;
2665
+ try {
2666
+ (p = g.dispose) == null || p.call(g);
2667
+ } catch (v) {
2668
+ console.warn(`[xr-sdk registry] dispose threw for ${y}`, v);
2669
+ }
2670
+ };
2671
+ return {
2672
+ acquire: async (y, g, p) => {
2673
+ let v = n.get(y);
2674
+ if (v)
2675
+ return v.refs.add(g), v.activeRefs.add(g), v.initPromise;
2676
+ const A = s[y];
2677
+ if (!A)
2678
+ throw new Error(`Invalid model: ${y}`);
2679
+ const E = new A(), B = /* @__PURE__ */ new Set([g]), K = /* @__PURE__ */ new Set([g]);
2680
+ o(y, null);
2681
+ const O = (async () => {
2682
+ await E.initialize(p);
2683
+ const I = n.get(y);
2684
+ if (!I || I.model !== E || I.refs.size === 0)
2685
+ return a(y, E), E;
2686
+ t && await t(y, E);
2687
+ const G = n.get(y);
2688
+ return G && G.refs.size > 0 && (i.add(E), e.setPipeline((X) => X.set(y, E))), E;
2689
+ })();
2690
+ return v = { model: E, refs: B, activeRefs: K, initPromise: O, options: p }, n.set(y, v), O.catch((I) => {
2691
+ n.get(y) === v && (n.delete(y), e.setPipeline((X) => X.delete(y)), o(y, I instanceof Error ? I : new Error(String(I)))), a(y, E);
2692
+ }), O;
2693
+ },
2694
+ release: (y, g) => {
2695
+ const p = n.get(y);
2696
+ p && (p.refs.delete(g), p.activeRefs.delete(g) && p.refs.size > 0 && p.activeRefs.size === 0 && p.model.pause(), !(p.refs.size > 0) && (n.delete(y), a(y, p.model), e.setPipeline((v) => v.delete(y))));
2697
+ },
2698
+ setActive: (y, g, p) => {
2699
+ const v = n.get(y);
2700
+ if (!v || !v.refs.has(g)) return;
2701
+ const A = v.activeRefs.size > 0;
2702
+ p ? v.activeRefs.add(g) : v.activeRefs.delete(g);
2703
+ const E = v.activeRefs.size > 0;
2704
+ A !== E && (E && !r ? v.model.resume() : v.model.pause());
2705
+ },
2706
+ suspendAll: () => {
2707
+ r = !0;
2708
+ for (const y of n.values())
2709
+ y.model.pause();
2710
+ },
2711
+ resumeActive: () => {
2712
+ r = !1;
2713
+ for (const y of n.values())
2714
+ y.activeRefs.size > 0 && y.model.resume();
2715
+ },
2716
+ get: (y) => {
2717
+ var g;
2718
+ return (g = n.get(y)) == null ? void 0 : g.model;
2719
+ },
2720
+ getOptions: (y) => {
2721
+ var g;
2722
+ return (g = n.get(y)) == null ? void 0 : g.options;
2723
+ },
2724
+ releaseAll: () => {
2725
+ for (const y of Array.from(n.keys())) {
2726
+ const g = n.get(y);
2727
+ g && (g.refs.clear(), n.delete(y), a(y, g.model));
2728
+ }
2729
+ e.setPipeline((y) => y.clear());
2730
+ },
2731
+ getState: (y) => {
2732
+ const g = n.get(y);
2733
+ return g ? i.has(g.model) ? "ready" : "initializing" : e.getSnapshot().modelErrors.has(y) ? "error" : "idle";
2734
+ },
2735
+ getOwners: (y) => {
2736
+ const g = n.get(y);
2737
+ return {
2738
+ refs: g ? Array.from(g.refs) : [],
2739
+ active: g ? Array.from(g.activeRefs) : []
2740
+ };
2741
+ }
2742
+ };
2743
+ }, Fi = {
2744
+ lifecycle: "idle",
2745
+ ready: !1,
2746
+ error: void 0,
2747
+ cameraTexture: void 0,
2748
+ renderWidth: 0,
2749
+ renderHeight: 0,
2750
+ source: void 0,
2751
+ sourceKind: void 0,
2752
+ cameraFacing: null,
2753
+ cameraDeviceId: null,
2754
+ orientation: { type: "portrait", angle: 0 },
2755
+ quality: null,
2756
+ qualityConfig: null,
2757
+ sourceWidth: 0,
2758
+ sourceHeight: 0,
2759
+ cameraZoom: 1.2,
2760
+ pipeline: /* @__PURE__ */ new Map(),
2761
+ modelErrors: /* @__PURE__ */ new Map(),
2762
+ cameraPermission: "unknown",
2763
+ cameraPermissionReason: null,
2764
+ feedFrames: 0
2765
+ }, Pi = () => {
2766
+ let e = { ...Fi, pipeline: /* @__PURE__ */ new Map(), modelErrors: /* @__PURE__ */ new Map() };
2767
+ const s = /* @__PURE__ */ new Set(), t = () => {
2768
+ s.forEach((n) => n());
2769
+ };
2770
+ return {
2771
+ getSnapshot: () => e,
2772
+ set: (n) => {
2773
+ let i = !1;
2774
+ for (const r of Object.keys(n))
2775
+ if (n[r] !== e[r]) {
2776
+ i = !0;
2777
+ break;
2778
+ }
2779
+ i && (e = { ...e, ...n }, t());
2780
+ },
2781
+ setPipeline: (n) => {
2782
+ const i = new Map(e.pipeline);
2783
+ return n(i), e = { ...e, pipeline: i }, t(), i;
2784
+ },
2785
+ subscribe: (n) => (s.add(n), () => {
2786
+ s.delete(n);
2787
+ })
2788
+ };
2789
+ }, Ft = (e, s) => s ?? e === "user", _i = ({
2790
+ renderHeight: e,
2791
+ renderWidth: s,
2792
+ videoHeight: t,
2793
+ videoWidth: n
2794
+ }) => ({
2795
+ height: e || t,
2796
+ width: s || n
2797
+ }), Di = (e, s) => {
2798
+ const t = new fn({ verbose: !0 }), n = Pi();
2799
+ n.set({ cameraZoom: (e == null ? void 0 : e.cameraZoom) ?? 1.2 });
2800
+ let i = s, r = e;
2801
+ const o = (c) => {
2802
+ var S;
2803
+ const f = (S = q.getOptions(c)) == null ? void 0 : S.targetFps;
2804
+ return typeof f == "number" ? f : r == null ? void 0 : r.targetFps;
2805
+ };
2806
+ let a, d, l, h, m, w, M, x, b, T, R, y, g = !1, p = !1, v = !1, A = 0, E, B, K, O = !1, I = 0, G = /* @__PURE__ */ new WeakSet();
2807
+ const X = /* @__PURE__ */ new Set(), Me = (c) => {
2808
+ const f = n.getSnapshot().cameraTexture;
2809
+ f && f.dispose();
2810
+ const S = Ei(c);
2811
+ return n.set({ cameraTexture: S }), S;
2812
+ }, Ie = async (c, f) => {
2813
+ if (G.has(f) || n.getSnapshot().lifecycle !== "running" || !m) return;
2814
+ G.add(f);
2815
+ const S = I;
2816
+ try {
2817
+ await f.run({
2818
+ sourceCanvas: m,
2819
+ renderWidth: n.getSnapshot().renderWidth,
2820
+ renderHeight: n.getSnapshot().renderHeight,
2821
+ getSource: () => n.getSnapshot().sourceKind,
2822
+ targetFps: o(c),
2823
+ analysisScale: r == null ? void 0 : r.analysisScale
2824
+ }), O && (await new Promise((k) => requestAnimationFrame(() => k())), await new Promise((k) => requestAnimationFrame(() => k())), O && I === S && q.suspendAll());
2825
+ } catch (k) {
2826
+ throw G.delete(f), k;
2827
+ }
2828
+ }, q = Ii(n, It, (c, f) => Ie(c, f));
2829
+ n.subscribe(() => {
2830
+ if (n.getSnapshot().lifecycle !== "running") return;
2831
+ const c = n.getSnapshot().pipeline;
2832
+ for (const [f, S] of c.entries())
2833
+ G.has(S) || Ie(f, S);
2834
+ });
2835
+ const st = () => {
2836
+ y !== void 0 && (cancelAnimationFrame(y), y = void 0);
2837
+ }, ne = () => {
2838
+ if (st(), E == null || E(), E = void 0, d) {
2839
+ try {
2840
+ d.pause();
2841
+ } catch {
2842
+ }
2843
+ try {
2844
+ d.srcObject = null;
2845
+ } catch {
2846
+ }
2847
+ d = void 0;
2848
+ }
2849
+ if (l) {
2850
+ try {
2851
+ l.getTracks().forEach((c) => c.stop());
2852
+ } catch {
2853
+ }
2854
+ l = void 0;
2855
+ }
2856
+ }, Fe = () => {
2857
+ if (g || !d || !h || !m) return;
2858
+ const c = typeof window < "u" ? window.__xr_debugger_metrics : void 0;
2859
+ if (c != null && c.trackCameraFrame && c.trackCameraFrame(), Se(n.getSnapshot().sourceKind))
2860
+ Ri(d, h);
2861
+ else {
2862
+ const C = h.getContext("2d");
2863
+ if (!C) return;
2864
+ const D = d.videoWidth, L = d.videoHeight;
2865
+ h.width !== D && (h.width = D), h.height !== L && (h.height = L), C.setTransform(1, 0, 0, 1, 0, 0), C.clearRect(0, 0, D, L), C.drawImage(d, 0, 0, D, L);
2866
+ }
2867
+ Ai(h, m, (r == null ? void 0 : r.cameraZoom) ?? 1.2);
2868
+ const S = n.getSnapshot();
2869
+ (S.sourceWidth !== d.videoWidth || S.sourceHeight !== d.videoHeight) && n.set({ sourceWidth: d.videoWidth, sourceHeight: d.videoHeight }), A += 1, A % 10 === 0 && n.set({ feedFrames: A });
2870
+ const k = n.getSnapshot().cameraTexture;
2871
+ k && (k.needsUpdate = !0);
2872
+ }, Pe = () => {
2873
+ if (!d || !h || !m) return;
2874
+ if (O) {
2875
+ Fe();
2876
+ return;
2877
+ }
2878
+ const c = () => {
2879
+ y = requestAnimationFrame(c), Fe();
2880
+ };
2881
+ y = requestAnimationFrame(c);
2882
+ }, ts = async (c, f) => {
2883
+ if (c.source === P.WEBCAM)
2884
+ try {
2885
+ const S = r != null && r.camRes && r.camRes > 0 ? r.camRes : 960;
2886
+ n.set({ cameraPermission: "requesting", cameraPermissionReason: null });
2887
+ const k = c.deviceId ? { deviceId: { exact: c.deviceId } } : { facingMode: { ideal: c.facingMode ?? "user" } }, C = {
2888
+ frameRate: { min: 24, ideal: 30, max: 60 },
2889
+ width: { ideal: S },
2890
+ ...k
2891
+ };
2892
+ let D;
2893
+ try {
2894
+ D = await navigator.mediaDevices.getUserMedia({ video: C });
2895
+ } catch (L) {
2896
+ if (!(L instanceof DOMException && L.name === "OverconstrainedError")) throw L;
2897
+ D = await navigator.mediaDevices.getUserMedia({
2898
+ video: { frameRate: { ideal: 30 }, width: { ideal: S }, ...k }
2899
+ });
2900
+ }
2901
+ return f === I && n.set({ cameraPermission: "granted", cameraPermissionReason: null }), D;
2902
+ } catch (S) {
2903
+ const k = zt(S), C = St[k], D = await Wt(), L = qt(k, D.state);
2904
+ throw f === I && n.set({
2905
+ error: { error: "PermissionError", message: C, reason: k },
2906
+ cameraPermission: L.state,
2907
+ cameraPermissionReason: L.reason
2908
+ }), new N(S instanceof Error ? S.message : "getUserMedia failed");
2909
+ }
2910
+ return c.stream;
2911
+ }, nt = (c) => {
2912
+ const { lifecycle: f } = n.getSnapshot();
2913
+ f === "idle" || f === "stopped" || g || (ne(), q.suspendAll(), I += 1, a = void 0, n.set({
2914
+ lifecycle: "stopped",
2915
+ ready: !1,
2916
+ error: { error: "PermissionError", message: St[c], reason: c },
2917
+ cameraPermission: c === "permission-denied" ? "blocked" : "unavailable",
2918
+ cameraPermissionReason: Ut(c)
2919
+ }), t.log("XR session stopped: camera lost.", c));
2920
+ }, ss = (c) => {
2921
+ var k;
2922
+ E == null || E();
2923
+ const f = ((k = c.getVideoTracks) == null ? void 0 : k.call(c)) ?? [], S = () => {
2924
+ l === c && nt("camera-lost");
2925
+ };
2926
+ f.forEach((C) => {
2927
+ var D;
2928
+ return (D = C.addEventListener) == null ? void 0 : D.call(C, "ended", S);
2929
+ }), E = () => {
2930
+ f.forEach((C) => {
2931
+ var D;
2932
+ return (D = C.removeEventListener) == null ? void 0 : D.call(C, "ended", S);
2933
+ });
2934
+ };
2935
+ }, ns = async () => {
2936
+ if (B || typeof navigator > "u") return;
2937
+ const c = navigator.permissions;
2938
+ if (c != null && c.query)
2939
+ try {
2940
+ const f = await c.query({ name: "camera" });
2941
+ if (p) return;
2942
+ B = f, K = () => {
2943
+ f.state === "denied" && (a == null ? void 0 : a.source) === P.WEBCAM && nt("permission-denied");
2944
+ }, f.addEventListener("change", K);
2945
+ } catch {
2946
+ }
2947
+ }, is = () => {
2948
+ var c;
2949
+ B && K && ((c = B.removeEventListener) == null || c.call(B, "change", K)), B = void 0, K = void 0;
2950
+ }, _e = async (c) => {
2951
+ var ft, be, gt;
2952
+ const f = I, S = await ts(c, f);
2953
+ if (f !== I)
2954
+ throw S.getTracks().forEach((oe) => oe.stop()), new N("Media source superseded by a newer bind");
2955
+ l = S, ss(S);
2956
+ const k = await Ti(S);
2957
+ if (f !== I || p)
2958
+ throw S.getTracks().forEach((oe) => oe.stop()), new N("Media source superseded by a newer bind");
2959
+ d = k, h = new OffscreenCanvas(k.videoWidth, k.videoHeight);
2960
+ const { renderWidth: C, renderHeight: D } = n.getSnapshot(), L = _i({
2961
+ renderWidth: C,
2962
+ renderHeight: D,
2963
+ videoWidth: k.videoWidth,
2964
+ videoHeight: k.videoHeight
2965
+ });
2966
+ m ? (m.width !== L.width || m.height !== L.height) && (m.width = L.width, m.height = L.height, Me(m)) : (m = new OffscreenCanvas(L.width, L.height), Me(m));
2967
+ const mt = c.source === P.STREAM ? c.static === !0 : !1;
2968
+ O = mt;
2969
+ const ae = (gt = (be = (ft = S.getVideoTracks) == null ? void 0 : ft.call(S)[0]) == null ? void 0 : be.getSettings) == null ? void 0 : gt.call(be), Be = ae == null ? void 0 : ae.facingMode, Rs = Be === "user" || Be === "environment" ? Be : null;
2970
+ if (c.source === P.WEBCAM) {
2971
+ const oe = Rs ?? c.facingMode ?? "user", pt = Ft(oe, c.mirrored);
2972
+ a = {
2973
+ source: P.WEBCAM,
2974
+ sourceKind: pt ? "webcam" : "rear-camera",
2975
+ facingMode: oe,
2976
+ deviceId: c.deviceId,
2977
+ mirrored: pt
2978
+ };
2979
+ } else
2980
+ a = {
2981
+ source: P.STREAM,
2982
+ stream: c.stream,
2983
+ static: mt,
2984
+ sourceKind: c.sourceKind ?? "webcam"
2985
+ };
2986
+ n.set({
2987
+ source: c.source,
2988
+ sourceKind: a.sourceKind,
2989
+ cameraFacing: a.source === P.WEBCAM ? a.facingMode : null,
2990
+ cameraDeviceId: a.source === P.WEBCAM ? (ae == null ? void 0 : ae.deviceId) ?? a.deviceId ?? null : null,
2991
+ sourceWidth: k.videoWidth,
2992
+ sourceHeight: k.videoHeight,
2993
+ error: void 0
2994
+ }), c.source === P.WEBCAM && ns();
2995
+ }, De = async (c) => {
2996
+ const f = c.sourceKind ?? "webcam";
2997
+ m = c.canvas;
2998
+ const S = Me(m);
2999
+ n.set({
3000
+ cameraTexture: S,
3001
+ source: P.CANVAS,
3002
+ sourceKind: f,
3003
+ cameraFacing: null,
3004
+ cameraDeviceId: null,
3005
+ renderWidth: m.width,
3006
+ renderHeight: m.height,
3007
+ error: void 0
3008
+ }), a = {
3009
+ source: P.CANVAS,
3010
+ canvas: c.canvas,
3011
+ sourceKind: f
3012
+ };
3013
+ }, rs = (c, f) => {
3014
+ if (!f || c.source !== f.source) return !1;
3015
+ if (c.source === P.STREAM && f.source === P.STREAM)
3016
+ return c.stream === f.stream && (c.sourceKind ?? "webcam") === f.sourceKind;
3017
+ if (c.source === P.WEBCAM && f.source === P.WEBCAM) {
3018
+ const S = c.facingMode ?? "user";
3019
+ return S === f.facingMode && c.deviceId === f.deviceId && Ft(S, c.mirrored) === f.mirrored;
3020
+ }
3021
+ return !1;
3022
+ }, it = async () => {
3023
+ if (!m) return;
3024
+ const c = I, f = n.getSnapshot().pipeline;
3025
+ for (const [, S] of f.entries())
3026
+ S.resume();
3027
+ await new Promise((S) => requestAnimationFrame(() => S())), await new Promise((S) => requestAnimationFrame(() => S())), O && I === c && q.suspendAll();
3028
+ }, as = (c, f) => !f || f.source !== P.CANVAS ? !1 : c.canvas === f.canvas && (c.sourceKind ?? "webcam") === f.sourceKind, Oe = async (c) => {
3029
+ const f = c.source;
3030
+ if (f !== P.WEBCAM && f !== P.STREAM)
3031
+ throw new N(`Invalid media source: ${String(f)}`);
3032
+ if (p) throw new N("session.setMediaSource() called after the provider unmounted");
3033
+ if (rs(c, a)) {
3034
+ t.log("Media source unchanged, skipping rebind.");
3035
+ return;
3036
+ }
3037
+ I += 1;
3038
+ const { lifecycle: S } = n.getSnapshot();
3039
+ if (S === "idle" || S === "stopped") {
3040
+ await _e(c), n.set({ lifecycle: "media-bound" }), t.log("Media source set to:", c.source);
3041
+ return;
3042
+ }
3043
+ if (S === "media-bound") {
3044
+ ne(), await _e(c), t.log("Media source rebound to:", c.source);
3045
+ return;
3046
+ }
3047
+ const k = S === "paused";
3048
+ g = !0, await new Promise((C) => requestAnimationFrame(() => C())), ne();
3049
+ try {
3050
+ await _e(c);
3051
+ } finally {
3052
+ g = !1;
3053
+ }
3054
+ if (k) {
3055
+ d == null || d.pause(), t.log("Media source swapped (paused) to:", c.source);
3056
+ return;
3057
+ }
3058
+ Pe(), O ? await it() : q.resumeActive(), t.log("Media source swapped to:", c.source);
3059
+ }, os = async (c) => {
3060
+ if (p) throw new N("session.setFrameSource() called after the provider unmounted");
3061
+ if (as(c, a)) {
3062
+ t.log("Frame source unchanged, skipping rebind.");
3063
+ return;
3064
+ }
3065
+ I += 1;
3066
+ const { lifecycle: f } = n.getSnapshot();
3067
+ if (f === "idle" || f === "stopped") {
3068
+ await De(c), n.set({ lifecycle: "media-bound" }), t.log("Frame source set to canvas.");
3069
+ return;
3070
+ }
3071
+ if (f === "media-bound") {
3072
+ ne(), await De(c), t.log("Frame source rebound to canvas.");
3073
+ return;
3074
+ }
3075
+ g = !0, await new Promise((S) => requestAnimationFrame(() => S())), ne();
3076
+ try {
3077
+ await De(c);
3078
+ } finally {
3079
+ g = !1;
3080
+ }
3081
+ t.log("Frame source swapped to canvas.");
3082
+ }, rt = async () => {
3083
+ if (p) throw new N("session.start() called after the provider unmounted");
3084
+ const { lifecycle: c } = n.getSnapshot();
3085
+ if (c === "running") return;
3086
+ if (c === "paused") {
3087
+ await Le();
3088
+ return;
3089
+ }
3090
+ if (c === "idle")
3091
+ throw new N("session.start() called before setMediaSource — call setMediaSource first");
3092
+ if (!m)
3093
+ throw new N("session.start(): media source not bound");
3094
+ const f = (a == null ? void 0 : a.source) === P.CANVAS;
3095
+ if (!f && (!d || !h))
3096
+ throw c === "stopped" ? new N(
3097
+ "session.start() called from stopped state without a media source — call setMediaSource first"
3098
+ ) : new N("session.start(): media source not bound");
3099
+ f || Pe(), q.resumeActive(), n.set({ lifecycle: "running" }), await new Promise((k) => requestAnimationFrame(() => k()));
3100
+ const S = n.getSnapshot().pipeline;
3101
+ for (const [k, C] of S.entries())
3102
+ await Ie(k, C);
3103
+ n.set({ ready: !0 }), t.log("XR session started.");
3104
+ }, at = () => {
3105
+ if (n.getSnapshot().lifecycle === "running") {
3106
+ st(), q.suspendAll();
3107
+ try {
3108
+ d == null || d.pause();
3109
+ } catch {
3110
+ }
3111
+ n.set({ lifecycle: "paused" }), t.log("XR session paused.");
3112
+ }
3113
+ }, Le = async () => {
3114
+ if (p) throw new N("session.resume() called after the provider unmounted");
3115
+ n.getSnapshot().lifecycle === "paused" && (v = !1, d && d.play().catch(() => {
3116
+ }), (a == null ? void 0 : a.source) !== P.CANVAS && Pe(), n.set({ lifecycle: "running" }), O ? await it() : q.resumeActive(), t.log("XR session resumed."));
3117
+ }, cs = async (c = {}) => {
3118
+ await Oe({ source: P.WEBCAM, ...c });
3119
+ const { lifecycle: f } = n.getSnapshot();
3120
+ return (f === "media-bound" || f === "stopped") && await rt(), n.getSnapshot().cameraFacing ?? c.facingMode ?? "user";
3121
+ }, ot = async () => {
3122
+ const { lifecycle: c } = n.getSnapshot();
3123
+ c === "stopped" || c === "idle" || (v = !1, ne(), q.suspendAll(), a = void 0, n.set({ lifecycle: "stopped", ready: !1 }), t.log("XR session stopped."));
3124
+ }, ct = async () => {
3125
+ await ot(), q.releaseAll(), X.clear();
3126
+ const c = n.getSnapshot().cameraTexture;
3127
+ c && c.dispose(), G = /* @__PURE__ */ new WeakSet(), a = void 0, I += 1, m = void 0, h = void 0, M = void 0, O = !1, is(), n.set({
3128
+ lifecycle: "idle",
3129
+ cameraTexture: void 0,
3130
+ source: void 0,
3131
+ sourceKind: void 0,
3132
+ cameraFacing: null,
3133
+ cameraDeviceId: null,
3134
+ error: void 0,
3135
+ modelErrors: /* @__PURE__ */ new Map(),
3136
+ cameraPermission: "unknown",
3137
+ cameraPermissionReason: null
3138
+ }), t.log("XR session reset.");
3139
+ }, ls = async () => {
3140
+ p || (p = !0, re == null || re(), re = void 0, ie == null || ie(), ie = void 0, await ct(), t.log("XR session disposed."));
3141
+ }, ds = () => {
3142
+ p && (p = !1, ut(), ht(), t.log("XR session re-armed."));
3143
+ }, hs = () => p, us = async (c) => {
3144
+ const f = "legacy:registerXRPipeline", S = [];
3145
+ await Promise.all(
3146
+ c.map(async (k) => {
3147
+ const { model: C } = k;
3148
+ if (!It[C])
3149
+ throw new N(`Invalid model: ${C}`);
3150
+ X.has(C) || S.push(C);
3151
+ const D = "options" in k ? k.options : void 0;
3152
+ await q.acquire(C, f, D);
3153
+ })
3154
+ ), S.length > 0 && (S.forEach((k) => X.add(k)), t.log("XR pipeline registered."));
3155
+ }, ms = (c) => {
3156
+ const f = q.get(c);
3157
+ if (!f)
3158
+ throw new N(`Model ${c} is not registered in the pipeline`);
3159
+ return f.getModelNode();
3160
+ }, lt = async (c, f) => {
3161
+ c <= 0 || f <= 0 || (n.set({ renderWidth: c, renderHeight: f }), m && (m.width !== c || m.height !== f) && (m.width = c, m.height = f, Me(m), O && Fe()), t.log(`Source canvas set. Render size: ${c}x${f}`));
3162
+ }, fs = async (c) => {
3163
+ var C;
3164
+ w = c;
3165
+ const f = (C = c.getBoundingClientRect) == null ? void 0 : C.call(c), S = f && f.width > 0 ? Math.round(f.width) : c.clientWidth, k = f && f.height > 0 ? Math.round(f.height) : c.clientHeight;
3166
+ await lt(S, k);
3167
+ }, gs = (c) => {
3168
+ M = c;
3169
+ }, Ne = () => w && x && b && T ? w : M, ps = (c) => {
3170
+ x = c.renderer, b = c.scene, T = c.camera, R = c.renderFrame;
3171
+ }, dt = () => {
3172
+ if (!x || !b || !T)
3173
+ throw new N(
3174
+ "XR frame render requested before the R3F state was bound — make sure <XRScene> is mounted"
3175
+ );
3176
+ R ? R() : x.render(b, T);
3177
+ }, ys = () => {
3178
+ const c = w;
3179
+ if (c && Ne() === c)
3180
+ return dt(), c.toDataURL("image/png");
3181
+ const f = Ne();
3182
+ if (f) return f.toDataURL("image/png");
3183
+ throw new N(
3184
+ "session.captureFrame() called before an XRScene or XRMediaSurface capture target was bound"
3185
+ );
3186
+ }, ws = (c = 30) => {
3187
+ const f = Ne();
3188
+ if (!(f != null && f.captureStream))
3189
+ throw new N(
3190
+ "session.captureStream() called before an XRScene or XRMediaSurface capture target was bound"
3191
+ );
3192
+ return f.captureStream(c);
3193
+ }, vs = () => d, xs = () => m ?? null, Ss = (c) => {
3194
+ if (r = c, n.set({ cameraZoom: (c == null ? void 0 : c.cameraZoom) ?? 1.2 }), n.getSnapshot().lifecycle !== "running" || !m) return;
3195
+ const f = n.getSnapshot().pipeline;
3196
+ for (const [S, k] of f.entries())
3197
+ k.run({
3198
+ sourceCanvas: m,
3199
+ renderWidth: n.getSnapshot().renderWidth,
3200
+ renderHeight: n.getSnapshot().renderHeight,
3201
+ getSource: () => n.getSnapshot().sourceKind,
3202
+ targetFps: o(S),
3203
+ analysisScale: r == null ? void 0 : r.analysisScale
3204
+ });
3205
+ }, Ms = () => r, bs = async () => {
3206
+ if (!a || a.source !== P.WEBCAM) return;
3207
+ const { facingMode: c, deviceId: f, mirrored: S } = a;
3208
+ a = void 0, await Oe({ source: P.WEBCAM, facingMode: c, deviceId: f, mirrored: S });
3209
+ }, ks = (c) => {
3210
+ n.set({ quality: c });
3211
+ }, Cs = (c) => {
3212
+ n.set({ qualityConfig: c });
3213
+ }, Ts = (c) => {
3214
+ i = c;
3215
+ }, Es = () => {
3216
+ var C;
3217
+ if (typeof window > "u") return { type: "portrait", angle: 0 };
3218
+ const c = (C = window.screen) == null ? void 0 : C.orientation, f = (c == null ? void 0 : c.angle) ?? 0, S = f === 90 || f === 180 || f === 270 ? f : 0;
3219
+ return { type: c != null && c.type ? c.type.startsWith("landscape") ? "landscape" : "portrait" : window.innerWidth > window.innerHeight ? "landscape" : "portrait", angle: S };
3220
+ }, me = () => {
3221
+ const c = Es(), f = n.getSnapshot().orientation, S = f.type !== c.type || f.angle !== c.angle ? { orientation: c } : {};
3222
+ d && d.videoWidth > 0 && (S.sourceWidth = d.videoWidth, S.sourceHeight = d.videoHeight), Object.keys(S).length && n.set(S);
3223
+ };
3224
+ let ie;
3225
+ const ht = () => {
3226
+ var f, S, k;
3227
+ if (ie || typeof window > "u") return;
3228
+ const c = (f = window.screen) == null ? void 0 : f.orientation;
3229
+ (S = c == null ? void 0 : c.addEventListener) == null || S.call(c, "change", me), (k = window.addEventListener) == null || k.call(window, "resize", me), ie = () => {
3230
+ var C, D;
3231
+ (C = c == null ? void 0 : c.removeEventListener) == null || C.call(c, "change", me), (D = window.removeEventListener) == null || D.call(window, "resize", me);
3232
+ }, me();
3233
+ };
3234
+ let re;
3235
+ const ut = () => {
3236
+ if (re || typeof document > "u" || typeof document.addEventListener != "function") return;
3237
+ const c = () => {
3238
+ if (!p) {
3239
+ if (document.hidden) {
3240
+ i != null && i.pauseWhenHidden && n.getSnapshot().lifecycle === "running" && (at(), v = !0);
3241
+ return;
3242
+ }
3243
+ if (v && n.getSnapshot().lifecycle === "paused") {
3244
+ Le();
3245
+ return;
3246
+ }
3247
+ n.getSnapshot().lifecycle === "running" && (d != null && d.paused) && d.play().catch(() => {
3248
+ });
3249
+ }
3250
+ };
3251
+ document.addEventListener("visibilitychange", c), re = () => document.removeEventListener("visibilitychange", c);
3252
+ };
3253
+ return ut(), ht(), {
3254
+ store: n,
3255
+ registry: q,
3256
+ setMediaSource: Oe,
3257
+ start: rt,
3258
+ stop: ot,
3259
+ reset: ct,
3260
+ pause: at,
3261
+ resume: Le,
3262
+ switchCamera: cs,
3263
+ dispose: ls,
3264
+ rearm: ds,
3265
+ isDisposed: hs,
3266
+ setFrameSource: os,
3267
+ registerXRPipeline: us,
3268
+ getModelNode: ms,
3269
+ captureFrame: ys,
3270
+ captureStream: ws,
3271
+ getInputFrame: xs,
3272
+ _setRenderTarget: fs,
3273
+ _setCaptureTarget: gs,
3274
+ _setRenderSize: lt,
3275
+ _setR3FState: ps,
3276
+ _renderFrame: dt,
3277
+ _getVideoElement: vs,
3278
+ _setPerf: Ss,
3279
+ _setLifecycle: Ts,
3280
+ _rebindMedia: bs,
3281
+ _setQuality: ks,
3282
+ _setQualityConfig: Cs,
3283
+ _getPerf: Ms
3284
+ };
3285
+ }, Oi = (e, s) => {
3286
+ const t = he(e), n = he(s), i = xe(
3287
+ () => Di(t.current, n.current),
3288
+ []
3289
+ ), r = JSON.stringify(s ?? {});
3290
+ ye(() => {
3291
+ i._setLifecycle(s);
3292
+ }, [i, r]), ye(() => (i.rearm(), () => void i.dispose()), [i]);
3293
+ const o = JSON.stringify(e ?? {});
3294
+ return ye(() => {
3295
+ i._setPerf(e);
3296
+ }, [i, o]), i;
3297
+ }, Ye = /* @__PURE__ */ new Map(), Li = () => ({
3298
+ register: (e, s) => {
3299
+ s ? Ye.set(e, s) : Ye.delete(e);
3300
+ },
3301
+ resolve: (e) => e ? Ye.get(e) ?? null : null
3302
+ }), jt = Li(), Qt = _t(null), Ni = ({ children: e }) => {
3303
+ const s = he(/* @__PURE__ */ new Map()), t = wt((r, o) => {
3304
+ o ? s.current.set(r, o) : s.current.delete(r);
3305
+ }, []), n = wt(
3306
+ (r) => r ? s.current.get(r) ?? null : null,
3307
+ []
3308
+ ), i = xe(() => ({ register: t, resolve: n }), [t, n]);
3309
+ return Ps(Qt.Provider, { value: i }, e);
3310
+ }, Jt = () => Je(Qt) ?? jt, Yr = () => Jt().register, jr = () => Jt().resolve;
3311
+ jt.register;
3312
+ const Bi = {
3313
+ [F.FACE_TRACKER]: "face",
3314
+ [F.HAND_TRACKER]: "hand",
3315
+ [F.GESTURE_TRACKER]: "gesture",
3316
+ [F.BODY_TRACKER]: "body",
3317
+ [F.HOLISTIC_TRACKER]: "holistic",
3318
+ [F.BACKGROUND_SEGMENTATION]: "segmentation",
3319
+ [F.SEMANTIC_SEGMENTATION]: "semantic-seg"
3320
+ }, Pt = Object.values(F), Hi = (e, s) => {
3321
+ var n;
3322
+ const t = (n = e.registry.getOptions(s)) == null ? void 0 : n.targetFps;
3323
+ return typeof t == "number" ? t : null;
3324
+ }, Qe = (e, s, t, n = performance.now()) => {
3325
+ const i = e.store.getSnapshot(), r = t ? n - t.sampledAt : 0, o = t && r > 0 ? Math.max(0, (i.feedFrames - t.feedFrames) * 1e3 / r) : 0, a = i.lifecycle === "running", d = s.map((h) => {
3326
+ var T;
3327
+ const m = e.registry.getState(h), w = e.store.getSnapshot().pipeline.get(h), M = ((T = i.modelErrors.get(h)) == null ? void 0 : T.error) ?? null, x = (w == null ? void 0 : w.getDiagnostics()) ?? {
3328
+ inferenceMs: null,
3329
+ inferenceFps: 0,
3330
+ inferences: 0,
3331
+ skippedFrames: 0,
3332
+ detections: null,
3333
+ confidence: null,
3334
+ status: M ? "error" : "ready",
3335
+ error: M,
3336
+ paused: !1,
3337
+ disposed: !1
3338
+ };
3339
+ let b;
3340
+ return m === "error" || x.status === "error" ? b = "error" : m === "idle" ? b = "unavailable" : m === "initializing" ? b = "loading" : x.paused || !a ? b = "paused" : b = "ready", {
3341
+ ...x,
3342
+ error: x.error ?? M,
3343
+ model: h,
3344
+ label: Bi[h] ?? h,
3345
+ state: b,
3346
+ targetFps: Hi(e, h),
3347
+ owners: e.registry.getOwners(h)
3348
+ };
3349
+ }), l = i.quality;
3350
+ return {
3351
+ quality: l ? {
3352
+ tier: l.decision.tier.name,
3353
+ index: l.index,
3354
+ locked: l.locked,
3355
+ reason: l.decision.reason
3356
+ } : null,
3357
+ session: {
3358
+ lifecycle: i.lifecycle,
3359
+ ready: i.ready,
3360
+ error: i.error,
3361
+ source: i.source,
3362
+ sourceKind: i.sourceKind,
3363
+ sourceWidth: i.sourceWidth,
3364
+ sourceHeight: i.sourceHeight,
3365
+ renderWidth: i.renderWidth,
3366
+ renderHeight: i.renderHeight,
3367
+ feedFps: o,
3368
+ feedFrames: i.feedFrames
3369
+ },
3370
+ models: d,
3371
+ inferenceMsTotal: d.reduce(
3372
+ (h, m) => h + (m.state === "ready" ? m.inferenceMs ?? 0 : 0),
3373
+ 0
3374
+ ),
3375
+ sampledAt: n
3376
+ };
3377
+ }, Qr = (e = {}) => {
3378
+ const { intervalMs: s = 250, enabled: t = !0 } = e, { session: n } = es(), i = (e.models ?? Pt).join("|"), r = xe(
3379
+ () => e.models && e.models.length ? e.models : Pt,
3380
+ // modelsKey captures the list by value.
3381
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3382
+ [i]
3383
+ ), o = he(null), [a, d] = _s(
3384
+ () => Qe(n, r, null)
3385
+ );
3386
+ return ye(() => {
3387
+ if (!t) return;
3388
+ const l = () => {
3389
+ const m = Qe(n, r, o.current);
3390
+ o.current = { feedFrames: m.session.feedFrames, sampledAt: m.sampledAt }, d(m);
3391
+ };
3392
+ l();
3393
+ const h = window.setInterval(l, Math.max(50, s));
3394
+ return () => window.clearInterval(h);
3395
+ }, [n, r, s, t]), a;
3396
+ }, Ui = [
3397
+ { name: "high", targetFps: 30, renderScale: 1, analysisScale: 1, camRes: 960 },
3398
+ { name: "medium", targetFps: 24, renderScale: 0.8, analysisScale: 0.85, camRes: 720 },
3399
+ { name: "low", targetFps: 15, renderScale: 0.6, analysisScale: 0.7, camRes: 640 }
3400
+ ], Z = {
3401
+ maxFrameMs: 1e3 / 24,
3402
+ maxInferenceMs: 24,
3403
+ maxMemoryMb: null,
3404
+ sampleMs: 1e3,
3405
+ downgradeAfter: 2,
3406
+ upgradeAfter: 6,
3407
+ upgradeHeadroom: 0.75,
3408
+ cooldownMs: 4e3
3409
+ }, Zt = {
3410
+ frameMs: null,
3411
+ fps: null,
3412
+ inferenceMs: null,
3413
+ feedFps: null,
3414
+ memoryMb: null,
3415
+ deviceMemoryGb: null,
3416
+ hardwareConcurrency: null,
3417
+ thermal: "unknown"
3418
+ }, ve = (e, s, t) => Math.min(t, Math.max(s, e)), H = (e, s) => typeof e == "number" && Number.isFinite(e) ? e : s, zi = (e, s) => ({
3419
+ name: typeof e.name == "string" && e.name ? e.name : `tier-${s}`,
3420
+ ...H(e.targetFps, NaN) > 0 ? { targetFps: H(e.targetFps, 0) } : {},
3421
+ ...H(e.renderScale, NaN) > 0 ? { renderScale: ve(H(e.renderScale, 1), 0.25, 1) } : {},
3422
+ ...H(e.analysisScale, NaN) > 0 ? { analysisScale: ve(H(e.analysisScale, 1), 0.25, 1) } : {},
3423
+ ...H(e.camRes, NaN) > 0 ? { camRes: Math.round(H(e.camRes, 0)) } : {},
3424
+ ...e.rebindCamera ? { rebindCamera: !0 } : {}
3425
+ }), Wi = (e = {}) => ({
3426
+ maxFrameMs: Math.max(1, H(e.maxFrameMs, Z.maxFrameMs)),
3427
+ maxInferenceMs: Math.max(
3428
+ 0,
3429
+ H(e.maxInferenceMs, Z.maxInferenceMs)
3430
+ ),
3431
+ maxMemoryMb: e.maxMemoryMb === null || e.maxMemoryMb === void 0 ? null : Math.max(1, H(e.maxMemoryMb, 0)) || null,
3432
+ sampleMs: Math.max(100, H(e.sampleMs, Z.sampleMs)),
3433
+ downgradeAfter: Math.max(
3434
+ 1,
3435
+ Math.round(H(e.downgradeAfter, Z.downgradeAfter))
3436
+ ),
3437
+ upgradeAfter: Math.max(
3438
+ 1,
3439
+ Math.round(H(e.upgradeAfter, Z.upgradeAfter))
3440
+ ),
3441
+ upgradeHeadroom: ve(
3442
+ H(e.upgradeHeadroom, Z.upgradeHeadroom),
3443
+ 0.1,
3444
+ 1
3445
+ ),
3446
+ cooldownMs: Math.max(0, H(e.cooldownMs, Z.cooldownMs))
3447
+ }), Q = (e, s, t) => {
3448
+ if (typeof s == "number" && Number.isInteger(s) && s >= 0 && s < e.length)
3449
+ return s;
3450
+ if (typeof s == "string") {
3451
+ const n = e.findIndex((i) => i.name === s);
3452
+ if (n >= 0) return n;
3453
+ }
3454
+ return t;
3455
+ }, qi = (e = {}) => {
3456
+ const s = e.tiers && e.tiers.length ? e.tiers.map((i, r) => zi(i, r)) : Ui, t = Q(s, e.maxTier, 0), n = Math.max(t, Q(s, e.minTier, s.length - 1));
3457
+ return {
3458
+ tiers: s,
3459
+ budget: Wi(e.budget),
3460
+ ...e.initialTier !== void 0 ? { initialTier: e.initialTier } : {},
3461
+ minTier: n,
3462
+ maxTier: t,
3463
+ adaptive: e.adaptive !== !1,
3464
+ historySize: Math.max(1, Math.round(H(e.historySize, 20)))
3465
+ };
3466
+ }, Vi = (e, s) => {
3467
+ const t = Q(e.tiers, e.maxTier, 0), n = Q(e.tiers, e.minTier, e.tiers.length - 1);
3468
+ if (e.initialTier !== void 0)
3469
+ return ve(Q(e.tiers, e.initialTier, t), t, n);
3470
+ const i = s.deviceMemoryGb !== null && s.deviceMemoryGb <= 4 || s.hardwareConcurrency !== null && s.hardwareConcurrency <= 4;
3471
+ return ve(i ? t + 1 : t, t, n);
3472
+ }, $t = (e, s = Zt, t = 0) => {
3473
+ const n = Vi(e, s), i = { index: n, tier: e.tiers[n], reason: "init", at: t };
3474
+ return {
3475
+ index: n,
3476
+ locked: !1,
3477
+ badStreak: 0,
3478
+ goodStreak: 0,
3479
+ lastChangeAt: t,
3480
+ decision: i,
3481
+ history: [i],
3482
+ signals: s
3483
+ };
3484
+ }, Ae = (e, s, t, n, i, r = e.signals) => {
3485
+ const o = { index: t, tier: s.tiers[t], reason: n, at: i };
3486
+ return {
3487
+ ...e,
3488
+ index: t,
3489
+ badStreak: 0,
3490
+ goodStreak: 0,
3491
+ lastChangeAt: i,
3492
+ decision: o,
3493
+ history: [o, ...e.history].slice(0, s.historySize),
3494
+ signals: r
3495
+ };
3496
+ }, Ki = (e, s) => e.thermal === "critical" ? "thermal" : s.maxMemoryMb !== null && e.memoryMb !== null && e.memoryMb > s.maxMemoryMb ? "memory" : e.inferenceMs !== null && e.inferenceMs > s.maxInferenceMs ? "inference" : e.frameMs !== null && e.frameMs > s.maxFrameMs ? "frame-time" : null, Gi = (e, s, t, n) => {
3497
+ const { budget: i } = t, r = Q(t.tiers, t.maxTier, 0), o = Q(t.tiers, t.minTier, t.tiers.length - 1);
3498
+ if (e.locked || !t.adaptive) return { ...e, signals: s };
3499
+ const a = Ki(s, i), d = a === null && s.frameMs !== null && s.frameMs <= i.maxFrameMs * i.upgradeHeadroom && (s.inferenceMs === null || s.inferenceMs <= i.maxInferenceMs * i.upgradeHeadroom), l = a ? e.badStreak + 1 : 0, h = d ? e.goodStreak + 1 : 0, m = n - e.lastChangeAt >= i.cooldownMs;
3500
+ if (a && l >= i.downgradeAfter && m) {
3501
+ if (e.index < o)
3502
+ return Ae(e, t, e.index + 1, a, n, s);
3503
+ const w = a === "frame-time" ? "suspected" : s.thermal;
3504
+ return { ...e, badStreak: l, goodStreak: h, signals: { ...s, thermal: w } };
3505
+ }
3506
+ return d && h >= i.upgradeAfter && m && e.index > r ? Ae(e, t, e.index - 1, "recovered", n, s) : { ...e, badStreak: l, goodStreak: h, signals: s };
3507
+ }, Jr = (e, s, t, n) => {
3508
+ const i = Q(s.tiers, t, e.index);
3509
+ return i === e.index ? e : Ae(e, s, i, "manual", n);
3510
+ }, Zr = (e, s, t, n) => t === e.locked ? e : { ...Ae(e, s, e.index, t ? "locked" : "manual", n), locked: t }, Xi = (e, s) => e.decision.tier === s ? null : e.decision.tier, $r = (e, s, t) => {
3511
+ const n = $t(e, s, t);
3512
+ return {
3513
+ ...n,
3514
+ decision: { ...n.decision, reason: "reset" },
3515
+ history: [{ ...n.decision, reason: "reset" }]
3516
+ };
3517
+ }, Yi = Object.values(F), ji = () => {
3518
+ if (typeof navigator > "u") return { deviceMemoryGb: null, hardwareConcurrency: null };
3519
+ const e = navigator;
3520
+ return {
3521
+ deviceMemoryGb: typeof e.deviceMemory == "number" ? e.deviceMemory : null,
3522
+ hardwareConcurrency: typeof e.hardwareConcurrency == "number" ? e.hardwareConcurrency : null
3523
+ };
3524
+ }, Qi = () => {
3525
+ const e = performance.memory;
3526
+ return e ? e.usedJSHeapSize / 1048576 : null;
3527
+ }, Ji = ({ config: e, thermal: s, onDecision: t }) => {
3528
+ const { session: n } = es(), i = JSON.stringify(e ?? {}), r = xe(() => qi(e), [i]), o = he(s ?? "unknown");
3529
+ o.current = s ?? "unknown";
3530
+ const a = he(t);
3531
+ return a.current = t, ye(() => {
3532
+ const d = ji();
3533
+ let l = $t(
3534
+ r,
3535
+ { ...Zt, ...d },
3536
+ performance.now()
3537
+ );
3538
+ const h = n.store.getSnapshot().quality;
3539
+ h && h.index < r.tiers.length && (l = {
3540
+ ...h,
3541
+ decision: { ...h.decision, tier: r.tiers[h.index] }
3542
+ }), n._setQualityConfig(r), n._setQuality(l);
3543
+ let m = n._getPerf(), w = null;
3544
+ const M = async (p, v) => {
3545
+ const A = {
3546
+ ...m,
3547
+ ...p.targetFps !== void 0 ? { targetFps: p.targetFps } : {},
3548
+ ...p.analysisScale !== void 0 ? { analysisScale: p.analysisScale } : {},
3549
+ ...p.camRes !== void 0 && p.rebindCamera ? { camRes: p.camRes } : {}
3550
+ };
3551
+ n._setPerf(A), p.rebindCamera && p.camRes !== void 0 && p.camRes !== (v == null ? void 0 : v.camRes) && await n._rebindMedia().catch(() => {
3552
+ });
3553
+ };
3554
+ w = l.decision.tier, M(l.decision.tier, null);
3555
+ let x = 0, b = performance.now(), T = 0;
3556
+ const R = () => {
3557
+ x += 1, T = requestAnimationFrame(R);
3558
+ };
3559
+ T = requestAnimationFrame(R);
3560
+ let y = null;
3561
+ const g = window.setInterval(() => {
3562
+ var G;
3563
+ if (typeof document < "u" && document.hidden) {
3564
+ x = 0, b = performance.now();
3565
+ return;
3566
+ }
3567
+ const p = performance.now(), v = p - b, A = Qe(n, Yi, y, p);
3568
+ y = { feedFrames: A.session.feedFrames, sampledAt: p };
3569
+ const E = n.store.getSnapshot().lifecycle === "running", B = {
3570
+ frameMs: x > 0 && v > 0 && E ? v / x : null,
3571
+ fps: x > 0 && v > 0 ? x * 1e3 / v : null,
3572
+ inferenceMs: E ? A.inferenceMsTotal : null,
3573
+ feedFps: A.session.feedFps,
3574
+ memoryMb: Qi(),
3575
+ ...d,
3576
+ thermal: o.current
3577
+ };
3578
+ x = 0, b = p;
3579
+ const K = n.store.getSnapshot().quality ?? l, O = Gi(K, B, r, p);
3580
+ l = O, n._setQuality(O);
3581
+ const I = Xi(O, w);
3582
+ if (I) {
3583
+ const X = w;
3584
+ w = I, M(I, X), (G = a.current) == null || G.call(a, O);
3585
+ }
3586
+ }, r.budget.sampleMs);
3587
+ return () => {
3588
+ cancelAnimationFrame(T), window.clearInterval(g);
3589
+ const p = (w == null ? void 0 : w.rebindCamera) && w.camRes !== void 0;
3590
+ n._setPerf(m), p && (m == null ? void 0 : m.camRes) !== (w == null ? void 0 : w.camRes) && n._rebindMedia().catch(() => {
3591
+ }), m = void 0, n._setQualityConfig(null);
3592
+ };
3593
+ }, [n, r]), null;
3594
+ }, tt = _t(void 0), es = () => {
3595
+ const e = Je(tt);
3596
+ if (!e)
3597
+ throw new N(
3598
+ "XR context can only be used inside XRProvider, did you forget to wrap your app in <XRProvider>?"
3599
+ );
3600
+ return e;
3601
+ }, ea = () => Je(tt) ?? null, ta = ({ children: e, perf: s, lifecycle: t, quality: n }) => {
3602
+ const i = Oi(s, t), r = xe(() => ({ session: i }), [i]);
3603
+ return /* @__PURE__ */ Fs(tt.Provider, { value: r, children: [
3604
+ n !== !1 && /* @__PURE__ */ yt(Ji, { config: n || void 0 }),
3605
+ /* @__PURE__ */ yt(Ni, { children: e })
3606
+ ] });
3607
+ };
3608
+ export {
3609
+ Cr as $,
3610
+ ii as A,
3611
+ pe as B,
3612
+ ue as C,
3613
+ Kr as D,
3614
+ Zt as E,
3615
+ Xr as F,
3616
+ xi as G,
3617
+ ci as H,
3618
+ Ks as I,
3619
+ W as J,
3620
+ pr as K,
3621
+ V as L,
3622
+ J as M,
3623
+ jr as N,
3624
+ yr as O,
3625
+ Ce as P,
3626
+ Ze as Q,
3627
+ Wt as R,
3628
+ At as S,
3629
+ or as T,
3630
+ cr as U,
3631
+ lr as V,
3632
+ dr as W,
3633
+ Tt as X,
3634
+ ta as Y,
3635
+ Cn as Z,
3636
+ Mr as _,
3637
+ Jr as a,
3638
+ kn as a$,
3639
+ Gt as a0,
3640
+ wr as a1,
3641
+ br as a2,
3642
+ Tr as a3,
3643
+ Rn as a4,
3644
+ xr as a5,
3645
+ Rr as a6,
3646
+ Sr as a7,
3647
+ vr as a8,
3648
+ kr as a9,
3649
+ Vt as aA,
3650
+ Nt as aB,
3651
+ Xs as aC,
3652
+ Ys as aD,
3653
+ js as aE,
3654
+ In as aF,
3655
+ Nr as aG,
3656
+ Or as aH,
3657
+ Pn as aI,
3658
+ Gs as aJ,
3659
+ Qe as aK,
3660
+ zt as aL,
3661
+ qt as aM,
3662
+ Qr as aN,
3663
+ Bi as aO,
3664
+ an as aP,
3665
+ $t as aQ,
3666
+ Ki as aR,
3667
+ ji as aS,
3668
+ Vi as aT,
3669
+ Wi as aU,
3670
+ zi as aV,
3671
+ Gi as aW,
3672
+ Xi as aX,
3673
+ Si as aY,
3674
+ Gr as aZ,
3675
+ vn as a_,
3676
+ Er as aa,
3677
+ Pr as ab,
3678
+ mn as ac,
3679
+ Ar as ad,
3680
+ Ir as ae,
3681
+ ur as af,
3682
+ mr as ag,
3683
+ fr as ah,
3684
+ gr as ai,
3685
+ _r as aj,
3686
+ hr as ak,
3687
+ An as al,
3688
+ Fr as am,
3689
+ Hr as an,
3690
+ Ur as ao,
3691
+ ni as ap,
3692
+ oi as aq,
3693
+ Bt as ar,
3694
+ en as as,
3695
+ Ht as at,
3696
+ rr as au,
3697
+ Z as av,
3698
+ Ui as aw,
3699
+ Ji as ax,
3700
+ je as ay,
3701
+ li as az,
3702
+ $r as b,
3703
+ Mt as b0,
3704
+ hi as b1,
3705
+ di as b2,
3706
+ ui as b3,
3707
+ pn as b4,
3708
+ wn as b5,
3709
+ yn as b6,
3710
+ Yr as b7,
3711
+ zr as b8,
3712
+ Bn as b9,
3713
+ Gn as ba,
3714
+ Xn as bb,
3715
+ te as bc,
3716
+ un as c,
3717
+ ir as d,
3718
+ Vr as e,
3719
+ Fn as f,
3720
+ Dr as g,
3721
+ Lr as h,
3722
+ Se as i,
3723
+ F as j,
3724
+ Wr as k,
3725
+ Zr as l,
3726
+ ar as m,
3727
+ _n as n,
3728
+ qe as o,
3729
+ qr as p,
3730
+ Ln as q,
3731
+ qi as r,
3732
+ Ut as s,
3733
+ Br as t,
3734
+ es as u,
3735
+ Nn as v,
3736
+ P as w,
3737
+ ea as x,
3738
+ _ as y,
3739
+ hn as z
3740
+ };