@therealtinhtute/baroiplayer 1.1.0 → 1.2.1

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 (142) hide show
  1. package/README.md +1 -2
  2. package/dist/context/media.js +1 -2
  3. package/dist/context/media.mjs +3 -15
  4. package/dist/context/store.js +1 -2
  5. package/dist/context/store.mjs +3 -5
  6. package/dist/context-Bzd5QCKM.cjs +7 -0
  7. package/dist/context-Bzd5QCKM.cjs.map +1 -0
  8. package/dist/context-DD_SH4tT.js +1053 -0
  9. package/dist/context-DD_SH4tT.js.map +1 -0
  10. package/dist/core-events-BRnLMB7s.cjs +2 -0
  11. package/dist/core-events-BRnLMB7s.cjs.map +1 -0
  12. package/dist/core-events-v_mKdj5p.js +417 -0
  13. package/dist/core-events-v_mKdj5p.js.map +1 -0
  14. package/dist/core-plugins-CMBv-yVh.cjs +2 -0
  15. package/dist/core-plugins-CMBv-yVh.cjs.map +1 -0
  16. package/dist/core-plugins-CqCxLkbd.js +754 -0
  17. package/dist/core-plugins-CqCxLkbd.js.map +1 -0
  18. package/dist/core.js +7 -29
  19. package/dist/core.js.map +1 -1
  20. package/dist/core.mjs +947 -1220
  21. package/dist/core.mjs.map +1 -1
  22. package/dist/enhanced-components-BwjBqSA1.js +2858 -0
  23. package/dist/enhanced-components-BwjBqSA1.js.map +1 -0
  24. package/dist/enhanced-components-C-ka-XLp.cjs +2 -0
  25. package/dist/enhanced-components-C-ka-XLp.cjs.map +1 -0
  26. package/dist/hooks-B-IIWPJr.js +1842 -0
  27. package/dist/hooks-B-IIWPJr.js.map +1 -0
  28. package/dist/hooks-DcHzmBwA.cjs +4 -0
  29. package/dist/hooks-DcHzmBwA.cjs.map +1 -0
  30. package/dist/index.js +27 -97
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +5613 -6210
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/minimal-components-BYsMQde5.js +1610 -0
  35. package/dist/minimal-components-BYsMQde5.js.map +1 -0
  36. package/dist/minimal-components-CsxQbDp7.cjs +2 -0
  37. package/dist/minimal-components-CsxQbDp7.cjs.map +1 -0
  38. package/dist/performance-monitor-DCSijLJg.js +312 -0
  39. package/dist/performance-monitor-DCSijLJg.js.map +1 -0
  40. package/dist/performance-monitor-wNFKmqMr.cjs +2 -0
  41. package/dist/performance-monitor-wNFKmqMr.cjs.map +1 -0
  42. package/dist/rolldown-runtime-BmowowmI.js +14 -0
  43. package/dist/rolldown-runtime-mLOUI7ql.cjs +1 -0
  44. package/dist/utils-D2gQ7c2R.js +64 -0
  45. package/dist/utils-D2gQ7c2R.js.map +1 -0
  46. package/dist/utils-DJaAwiZ9.cjs +2 -0
  47. package/dist/utils-DJaAwiZ9.cjs.map +1 -0
  48. package/dist/utils.js +1 -2
  49. package/dist/utils.mjs +3 -11
  50. package/package.json +28 -22
  51. package/src/components/AnimateLoading.tsx +14 -10
  52. package/src/components/accessibility/keyboard-help-overlay.tsx +2 -0
  53. package/src/components/enhanced/debug-panel.tsx +1 -1
  54. package/src/components/enhanced/enhanced-media-player.tsx +68 -25
  55. package/src/components/examples/loading-states-demo.tsx +1 -2
  56. package/src/components/examples/react-19-demo.tsx +6 -10
  57. package/src/components/examples/volume-orientation-demo.tsx +1 -2
  58. package/src/components/legacy.tsx +6 -6
  59. package/src/components/media-player-video.tsx +5 -12
  60. package/src/components/media-player.tsx +2 -2
  61. package/src/components/ui/blur-poster.tsx +18 -15
  62. package/src/components/ui/enhanced-seek-bar.tsx +2 -2
  63. package/src/components/ui/media-resource-preloader.tsx +21 -23
  64. package/src/components/unified/base-media-player.tsx +22 -10
  65. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +58 -38
  66. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +6 -6
  67. package/src/components/variants/minimal/components/VideoElement.tsx +3 -1
  68. package/src/core/optimization/bundle-optimizer.tsx +26 -27
  69. package/src/core/performance/media-loading-optimizer.ts +2 -1
  70. package/src/core/plugins/__tests__/registry.test.ts +1 -1
  71. package/src/core/plugins/enhanced-plugin-system.ts +26 -8
  72. package/src/core/plugins/registry.ts +319 -92
  73. package/src/core/plugins/types.ts +21 -3
  74. package/src/core/providers/enhanced-hls-provider.ts +11 -40
  75. package/src/core/providers/lazy-provider.tsx +5 -42
  76. package/src/features/media-session/media-session-manager.ts +4 -26
  77. package/src/features/picture-in-picture/pip-manager.ts +2 -2
  78. package/src/features/playlist/playlist-manager.ts +26 -18
  79. package/src/features/subtitles/subtitle-manager.ts +1 -1
  80. package/src/features/subtitles/subtitle-parser.ts +19 -16
  81. package/src/features/thumbnails/thumbnail-generator.ts +12 -5
  82. package/src/hooks/__tests__/currentTime-fix.test.ts +149 -0
  83. package/src/hooks/accessibility/use-accessibility-preferences.ts +1 -1
  84. package/src/hooks/accessibility/use-focus-management.ts +2 -2
  85. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +2 -2
  86. package/src/hooks/accessibility/use-screen-reader.ts +1 -1
  87. package/src/hooks/core/index.ts +1 -1
  88. package/src/hooks/use-buffer-health.ts +1 -1
  89. package/src/hooks/use-enhanced-media-player.ts +107 -9
  90. package/src/hooks/use-focus-trap.tsx +2 -2
  91. package/src/hooks/use-intelligent-preloading.ts +23 -3
  92. package/src/hooks/use-keyboard-shortcuts.ts +2 -2
  93. package/src/hooks/use-media-player.ts +74 -43
  94. package/src/hooks/use-memory-optimization.ts +15 -15
  95. package/src/hooks/use-smart-preload.ts +1 -2
  96. package/src/hooks/useKeyboardShortcuts.ts +34 -2
  97. package/src/hooks/useScreenshot.ts +60 -44
  98. package/src/hooks/useVideoPlayer.ts +50 -4
  99. package/src/index-legacy.ts +3 -5
  100. package/src/test/accessibility-utils.ts +7 -7
  101. package/src/test/media-mocks.ts +41 -28
  102. package/src/test/setup.ts +22 -4
  103. package/src/types/assets.d.ts +29 -0
  104. package/src/types/index.ts +13 -0
  105. package/dist/context/media.js.map +0 -1
  106. package/dist/context/media.mjs.map +0 -1
  107. package/dist/context/store.js.map +0 -1
  108. package/dist/context/store.mjs.map +0 -1
  109. package/dist/context-BYwDoSRX.js +0 -1172
  110. package/dist/context-BYwDoSRX.js.map +0 -1
  111. package/dist/context-eNS62_ac.cjs +0 -23
  112. package/dist/context-eNS62_ac.cjs.map +0 -1
  113. package/dist/core-events-B1iM2F46.cjs +0 -2
  114. package/dist/core-events-B1iM2F46.cjs.map +0 -1
  115. package/dist/core-events-DunPHKRE.js +0 -484
  116. package/dist/core-events-DunPHKRE.js.map +0 -1
  117. package/dist/core-plugins-CROGvQUy.js +0 -686
  118. package/dist/core-plugins-CROGvQUy.js.map +0 -1
  119. package/dist/core-plugins-DtsHBOtF.cjs +0 -2
  120. package/dist/core-plugins-DtsHBOtF.cjs.map +0 -1
  121. package/dist/enhanced-components-DUw2KrmQ.js +0 -1142
  122. package/dist/enhanced-components-DUw2KrmQ.js.map +0 -1
  123. package/dist/enhanced-components-DXBCHU0v.cjs +0 -2
  124. package/dist/enhanced-components-DXBCHU0v.cjs.map +0 -1
  125. package/dist/hooks-BW-JjVgP.cjs +0 -4
  126. package/dist/hooks-BW-JjVgP.cjs.map +0 -1
  127. package/dist/hooks-CyX6De5M.js +0 -1693
  128. package/dist/hooks-CyX6De5M.js.map +0 -1
  129. package/dist/minimal-components-Bdcpxav5.cjs +0 -2
  130. package/dist/minimal-components-Bdcpxav5.cjs.map +0 -1
  131. package/dist/minimal-components-DlRK7Qu_.js +0 -1927
  132. package/dist/minimal-components-DlRK7Qu_.js.map +0 -1
  133. package/dist/performance-monitor-C5k6FDXw.js +0 -301
  134. package/dist/performance-monitor-C5k6FDXw.js.map +0 -1
  135. package/dist/performance-monitor-lJmuUjQQ.cjs +0 -2
  136. package/dist/performance-monitor-lJmuUjQQ.cjs.map +0 -1
  137. package/dist/utils-CFOue_9K.cjs +0 -9
  138. package/dist/utils-CFOue_9K.cjs.map +0 -1
  139. package/dist/utils-Dzpl2ArK.js +0 -2844
  140. package/dist/utils-Dzpl2ArK.js.map +0 -1
  141. package/dist/utils.js.map +0 -1
  142. package/dist/utils.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks-CyX6De5M.js","sources":["../src/hooks/use-media-actions.ts","../src/hooks/use-media-optimistic.ts","../src/hooks/use-enhanced-media-player.ts","../src/hooks/use-keyboard-controls.ts","../src/hooks/use-memory-optimization.ts","../src/hooks/use-media-state.ts","../src/hooks/use-media-player.ts","../../ui/src/hooks/use-mobile.ts","../src/hooks/use-touch-gestures.ts","../src/hooks/useEnhancedSubtitles.ts","../src/hooks/useKeyboardShortcuts.ts","../src/hooks/useMediaControls.ts","../src/hooks/useScreenshot.ts","../src/hooks/useVideoPlayer.ts","../src/hooks/use-intelligent-preloading.ts","../src/hooks/useSubtitles.ts","../src/hooks/legacy.ts"],"sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport type { MediaActionType, MediaState } from \"../context/media-context\"\nimport { MediaActionTypes } from \"../context/media-context\"\nimport type {\n\tEnhancedMediaStore,\n\tMediaActionState,\n\tOptimisticMediaAction\n} from \"../context/media-store\"\n\n// Action payload types\nexport interface MediaActionPayloads {\n\t[MediaActionTypes.PLAY]: void\n\t[MediaActionTypes.PAUSE]: void\n\t[MediaActionTypes.SEEK]: number\n\t[MediaActionTypes.SET_VOLUME]: number\n\t[MediaActionTypes.MUTE]: void\n\t[MediaActionTypes.UNMUTE]: void\n\t[MediaActionTypes.TOGGLE_MUTE]: void\n\t[MediaActionTypes.SET_DURATION]: number\n\t[MediaActionTypes.SET_CURRENT_TIME]: number\n\t[MediaActionTypes.SET_BUFFERED]: TimeRanges | null\n\t[MediaActionTypes.SET_LOADING]: boolean\n\t[MediaActionTypes.SET_ERROR]: string | null\n\t[MediaActionTypes.ENTER_FULLSCREEN]: void\n\t[MediaActionTypes.EXIT_FULLSCREEN]: void\n\t[MediaActionTypes.ENTER_PIP]: void\n\t[MediaActionTypes.EXIT_PIP]: void\n\t[MediaActionTypes.SET_PLAYBACK_RATE]: number\n\t[MediaActionTypes.SET_SUBTITLE_TRACK]: TextTrack | null\n\t[MediaActionTypes.SET_RENDITION]: string | null\n\t[MediaActionTypes.TOGGLE_SUBTITLES]: void\n\t[MediaActionTypes.PREVIEW_TIME]: number | null\n\t[MediaActionTypes.CLEAR_PREVIEW]: void\n}\n\n// Enhanced action creator that returns a Promise\ntype OptimisticActionCreator<T extends keyof MediaActionPayloads> =\n\tMediaActionPayloads[T] extends void\n\t\t? (optimistic?: boolean) => Promise<void>\n\t\t: (payload: MediaActionPayloads[T], optimistic?: boolean) => Promise<void>\n\n// Action creator factory\nfunction createOptimisticAction<T extends keyof MediaActionPayloads>(\n\ttype: T,\n\tstore: EnhancedMediaStore\n): OptimisticActionCreator<T> {\n\treturn ((payload?: any, optimistic = false) => {\n\t\tconst action: OptimisticMediaAction = {\n\t\t\ttype,\n\t\t\tdetail: payload,\n\t\t\toptimistic,\n\t\t\ttimestamp: Date.now()\n\t\t}\n\n\t\tif (optimistic) {\n\t\t\treturn store.dispatchOptimistic(action)\n\t\t} else {\n\t\t\tstore.dispatch(action)\n\t\t\treturn Promise.resolve()\n\t\t}\n\t}) as OptimisticActionCreator<T>\n}\n\n// React 19 useActionState integration\nexport function useMediaActionState(store: EnhancedMediaStore) {\n\tconst [actionState, setActionState] = React.useState<MediaActionState>(store.getActionState())\n\n\t// Subscribe to action state changes\n\tReact.useEffect(() => {\n\t\tconst unsubscribe = store.subscribe(() => {\n\t\t\tconst newActionState = store.getActionState()\n\t\t\tsetActionState((current) =>\n\t\t\t\tJSON.stringify(current) !== JSON.stringify(newActionState) ? newActionState : current\n\t\t\t)\n\t\t})\n\t\treturn unsubscribe\n\t}, [store])\n\n\treturn actionState\n}\n\n// Media actions hook with React 19 optimistic updates\nexport function useMediaActions(store: EnhancedMediaStore) {\n\t// Create action creators with optimistic support\n\tconst actions = React.useMemo(\n\t\t() => ({\n\t\t\t// Playback actions\n\t\t\tplay: createOptimisticAction(MediaActionTypes.PLAY, store),\n\t\t\tpause: createOptimisticAction(MediaActionTypes.PAUSE, store),\n\t\t\tseek: createOptimisticAction(MediaActionTypes.SEEK, store),\n\n\t\t\t// Volume actions\n\t\t\tsetVolume: createOptimisticAction(MediaActionTypes.SET_VOLUME, store),\n\t\t\tmute: createOptimisticAction(MediaActionTypes.MUTE, store),\n\t\t\tunmute: createOptimisticAction(MediaActionTypes.UNMUTE, store),\n\t\t\ttoggleMute: createOptimisticAction(MediaActionTypes.TOGGLE_MUTE, store),\n\n\t\t\t// Media state actions\n\t\t\tsetDuration: createOptimisticAction(MediaActionTypes.SET_DURATION, store),\n\t\t\tsetCurrentTime: createOptimisticAction(MediaActionTypes.SET_CURRENT_TIME, store),\n\t\t\tsetBuffered: createOptimisticAction(MediaActionTypes.SET_BUFFERED, store),\n\t\t\tsetLoading: createOptimisticAction(MediaActionTypes.SET_LOADING, store),\n\t\t\tsetError: createOptimisticAction(MediaActionTypes.SET_ERROR, store),\n\n\t\t\t// Display actions\n\t\t\tenterFullscreen: createOptimisticAction(MediaActionTypes.ENTER_FULLSCREEN, store),\n\t\t\texitFullscreen: createOptimisticAction(MediaActionTypes.EXIT_FULLSCREEN, store),\n\t\t\tenterPiP: createOptimisticAction(MediaActionTypes.ENTER_PIP, store),\n\t\t\texitPiP: createOptimisticAction(MediaActionTypes.EXIT_PIP, store),\n\n\t\t\t// Advanced actions\n\t\t\tsetPlaybackRate: createOptimisticAction(MediaActionTypes.SET_PLAYBACK_RATE, store),\n\t\t\tsetSubtitleTrack: createOptimisticAction(MediaActionTypes.SET_SUBTITLE_TRACK, store),\n\t\t\tsetRendition: createOptimisticAction(MediaActionTypes.SET_RENDITION, store),\n\t\t\ttoggleSubtitles: createOptimisticAction(MediaActionTypes.TOGGLE_SUBTITLES, store),\n\n\t\t\t// Preview actions\n\t\t\tpreviewTime: createOptimisticAction(MediaActionTypes.PREVIEW_TIME, store),\n\t\t\tclearPreview: createOptimisticAction(MediaActionTypes.CLEAR_PREVIEW, store)\n\t\t}),\n\t\t[store]\n\t)\n\n\t// Get action state for loading/error handling\n\tconst actionState = useMediaActionState(store)\n\n\t// Convenience methods that commonly use optimistic updates\n\tconst optimisticActions = React.useMemo(\n\t\t() => ({\n\t\t\t// These actions benefit from immediate UI feedback\n\t\t\ttogglePlayPause: async (isPlaying: boolean) => {\n\t\t\t\tif (isPlaying) {\n\t\t\t\t\tawait actions.pause(true) // optimistic\n\t\t\t\t} else {\n\t\t\t\t\tawait actions.play(true) // optimistic\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tseekWithPreview: async (time: number) => {\n\t\t\t\t// Immediate preview update, then actual seek\n\t\t\t\tawait actions.previewTime(time, true)\n\t\t\t\tawait actions.seek(time, true)\n\t\t\t},\n\n\t\t\tadjustVolume: async (delta: number, currentVolume: number) => {\n\t\t\t\tconst newVolume = Math.max(0, Math.min(1, currentVolume + delta))\n\t\t\t\tawait actions.setVolume(newVolume, true)\n\t\t\t},\n\n\t\t\ttoggleFullscreenOptimistic: async (isFullscreen: boolean) => {\n\t\t\t\tif (isFullscreen) {\n\t\t\t\t\tawait actions.exitFullscreen(true)\n\t\t\t\t} else {\n\t\t\t\t\tawait actions.enterFullscreen(true)\n\t\t\t\t}\n\t\t\t}\n\t\t}),\n\t\t[actions]\n\t)\n\n\t// Retry failed action\n\tconst retryLastAction = React.useCallback(async () => {\n\t\tconst { lastAction } = actionState\n\t\tif (lastAction && actionState.error) {\n\t\t\tawait store.dispatchOptimistic({\n\t\t\t\t...lastAction,\n\t\t\t\tretryCount: (lastAction.retryCount || 0) + 1\n\t\t\t})\n\t\t}\n\t}, [store, actionState])\n\n\treturn {\n\t\t...actions,\n\t\t...optimisticActions,\n\t\tactionState,\n\t\tretryLastAction,\n\t\tisLoading: actionState.pending,\n\t\thasError: !!actionState.error,\n\t\terrorMessage: actionState.error,\n\t\tretryCount: actionState.retryCount\n\t}\n}\n","\"use client\"\n\nimport React, { useOptimistic } from \"react\"\nimport type { MediaState } from \"../context/media-context\"\nimport type { EnhancedMediaStore, OptimisticMediaAction } from \"../context/media-store\"\n\n// Optimistic update reducer function\nfunction optimisticMediaReducer(state: MediaState, action: OptimisticMediaAction): MediaState {\n\tif (!action.optimistic) return state\n\n\t// Apply immediate optimistic updates for better UX\n\tswitch (action.type) {\n\t\tcase \"PLAY\":\n\t\t\treturn { ...state, isPlaying: true, error: null }\n\n\t\tcase \"PAUSE\":\n\t\t\treturn { ...state, isPlaying: false }\n\n\t\tcase \"SEEK\":\n\t\t\treturn { ...state, currentTime: action.detail }\n\n\t\tcase \"SET_VOLUME\":\n\t\t\treturn { ...state, volume: Math.max(0, Math.min(1, action.detail)) }\n\n\t\tcase \"MUTE\":\n\t\t\treturn { ...state, isMuted: true }\n\n\t\tcase \"UNMUTE\":\n\t\t\treturn { ...state, isMuted: false }\n\n\t\tcase \"TOGGLE_MUTE\":\n\t\t\treturn { ...state, isMuted: !state.isMuted }\n\n\t\tcase \"ENTER_FULLSCREEN\":\n\t\t\treturn { ...state, isFullscreen: true }\n\n\t\tcase \"EXIT_FULLSCREEN\":\n\t\t\treturn { ...state, isFullscreen: false }\n\n\t\tcase \"SET_PLAYBACK_RATE\":\n\t\t\treturn { ...state, playbackRate: action.detail }\n\n\t\tcase \"TOGGLE_SUBTITLES\":\n\t\t\treturn { ...state, subtitlesShowing: !state.subtitlesShowing }\n\n\t\tcase \"PREVIEW_TIME\":\n\t\t\treturn { ...state, previewTime: action.detail }\n\n\t\tcase \"CLEAR_PREVIEW\":\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tpreviewTime: null,\n\t\t\t\tpreviewImage: null,\n\t\t\t\tpreviewCoords: null\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn state\n\t}\n}\n\n// Media optimistic state hook using React 19's useOptimistic\nexport function useMediaOptimistic(store: EnhancedMediaStore) {\n\tconst actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState)\n\n\tconst [optimisticState, addOptimistic] = useOptimistic(actualState, optimisticMediaReducer)\n\n\t// Enhanced dispatch that uses optimistic updates\n\tconst dispatchOptimistic = React.useCallback(\n\t\tasync (action: OptimisticMediaAction) => {\n\t\t\t// Add optimistic update immediately\n\t\t\tif (action.optimistic) {\n\t\t\t\taddOptimistic(action)\n\t\t\t}\n\n\t\t\t// Dispatch the actual action\n\t\t\tawait store.dispatchOptimistic(action)\n\t\t},\n\t\t[store, addOptimistic]\n\t)\n\n\t// Quick actions with optimistic updates\n\tconst optimisticActions = React.useMemo(\n\t\t() => ({\n\t\t\t// Play/Pause with immediate feedback\n\t\t\ttogglePlayPause: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: optimisticState.isPlaying ? \"PAUSE\" : \"PLAY\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Volume control with immediate slider feedback\n\t\t\tsetVolumeOptimistic: async (volume: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SET_VOLUME\",\n\t\t\t\t\tdetail: Math.max(0, Math.min(1, volume)),\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Seek with immediate scrub feedback\n\t\t\tseekOptimistic: async (time: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SEEK\",\n\t\t\t\t\tdetail: time,\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Mute toggle with immediate icon change\n\t\t\ttoggleMuteOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"TOGGLE_MUTE\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Fullscreen toggle with immediate layout change\n\t\t\ttoggleFullscreenOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: optimisticState.isFullscreen ? \"EXIT_FULLSCREEN\" : \"ENTER_FULLSCREEN\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Playback rate with immediate feedback\n\t\t\tsetPlaybackRateOptimistic: async (rate: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SET_PLAYBACK_RATE\",\n\t\t\t\t\tdetail: rate,\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Subtitle toggle with immediate visibility change\n\t\t\ttoggleSubtitlesOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"TOGGLE_SUBTITLES\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t}\n\t\t}),\n\t\t[optimisticState, dispatchOptimistic]\n\t)\n\n\t// State selectors that return optimistic values\n\tconst selectors = React.useMemo(\n\t\t() => ({\n\t\t\tisPlaying: optimisticState.isPlaying,\n\t\t\tcurrentTime: optimisticState.currentTime,\n\t\t\tvolume: optimisticState.volume,\n\t\t\tisMuted: optimisticState.isMuted,\n\t\t\tisFullscreen: optimisticState.isFullscreen,\n\t\t\tplaybackRate: optimisticState.playbackRate,\n\t\t\tsubtitlesShowing: optimisticState.subtitlesShowing,\n\t\t\tpreviewTime: optimisticState.previewTime,\n\n\t\t\t// Computed values\n\t\t\tprogress:\n\t\t\t\toptimisticState.duration > 0 ? optimisticState.currentTime / optimisticState.duration : 0,\n\n\t\t\tformattedTime: formatTime(optimisticState.currentTime),\n\t\t\tformattedDuration: formatTime(optimisticState.duration),\n\n\t\t\t// State checks\n\t\t\tcanPlay: !optimisticState.isLoading && !optimisticState.error,\n\t\t\thasError: !!optimisticState.error,\n\t\t\tisBuffering: optimisticState.isLoading\n\t\t}),\n\t\t[optimisticState]\n\t)\n\n\treturn {\n\t\tstate: optimisticState,\n\t\tactualState,\n\t\t...selectors,\n\t\t...optimisticActions,\n\t\tdispatchOptimistic\n\t}\n}\n\n// Time formatting utility\nfunction formatTime(seconds: number): string {\n\tif (!seconds || !isFinite(seconds)) return \"0:00\"\n\n\tconst mins = Math.floor(seconds / 60)\n\tconst secs = Math.floor(seconds % 60)\n\tconst hours = Math.floor(mins / 60)\n\n\tif (hours > 0) {\n\t\treturn `${hours}:${String(mins % 60).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`\n\t}\n\n\treturn `${mins}:${String(secs).padStart(2, \"0\")}`\n}\n\n// Hook for components that need to detect optimistic updates\nexport function useOptimisticUpdates(store: EnhancedMediaStore) {\n\tconst [hasOptimisticUpdates, setHasOptimisticUpdates] = React.useState(false)\n\n\tReact.useEffect(() => {\n\t\tconst unsubscribe = store.subscribe(() => {\n\t\t\tconst actualState = store.getState()\n\t\t\tconst optimisticState = store.getOptimisticState()\n\n\t\t\tconst hasUpdates = JSON.stringify(actualState) !== JSON.stringify(optimisticState)\n\t\t\tsetHasOptimisticUpdates(hasUpdates)\n\t\t})\n\n\t\treturn unsubscribe\n\t}, [store])\n\n\treturn hasOptimisticUpdates\n}\n\n// Hook to get both actual and optimistic state for debugging\nexport function useMediaStateComparison(store: EnhancedMediaStore) {\n\tconst actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState)\n\n\tconst optimisticState = React.useSyncExternalStore(\n\t\tstore.subscribe,\n\t\tstore.getOptimisticState,\n\t\tstore.getOptimisticState\n\t)\n\n\tconst differences = React.useMemo(() => {\n\t\tconst diffs: any[] = []\n\n\t\tconst stateKeys = Object.keys(actualState) as Array<keyof MediaState>\n\t\tstateKeys.forEach((key) => {\n\t\t\tif (JSON.stringify(actualState[key]) !== JSON.stringify(optimisticState[key])) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\tkey: key as string,\n\t\t\t\t\tactual: actualState[key],\n\t\t\t\t\toptimistic: optimisticState[key]\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\treturn diffs\n\t}, [actualState, optimisticState])\n\n\treturn {\n\t\tactualState,\n\t\toptimisticState,\n\t\tdifferences,\n\t\thasOptimisticUpdates: differences.length > 0\n\t}\n}\n","\"use client\"\n\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseMemo,\n\tuseTransition,\n\tuseOptimistic,\n\tuseActionState\n} from \"react\"\nimport { useMediaSelector, useMediaStore } from \"../context/media-context\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\nimport type { MediaPlayerControls, MediaPlayerState } from \"../types/index\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\n\ninterface UseEnhancedMediaPlayerOptions {\n\tsrc: string | string[]\n\tautoPlay?: boolean\n\tloop?: boolean\n\tmuted?: boolean\n\tvolume?: number\n\tpreload?: \"none\" | \"metadata\" | \"auto\"\n\tcrossOrigin?: \"anonymous\" | \"use-credentials\"\n\tplaybackRates?: number[]\n\tkeyboardControls?: boolean\n\tshowControls?: boolean\n\tcustomControls?: boolean\n\tenablePerformanceMonitoring?: boolean\n\tbufferingStrategy?: \"aggressive\" | \"conservative\" | \"adaptive\"\n\t// Performance optimizations\n\tenableTimeUpdateThrottling?: boolean\n\ttimeUpdateThrottleMs?: number\n\tenableSeekPreview?: boolean\n\tpreloadStrategy?: \"eager\" | \"lazy\" | \"progressive\"\n}\n\n// Performance-optimized media player hook with React 19 features\nexport function useEnhancedMediaPlayer(options: UseEnhancedMediaPlayerOptions) {\n\tconst mediaRef = useRef<HTMLVideoElement | HTMLAudioElement>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\n\t// React 19 concurrent features\n\tconst [isPending, startTransition] = useTransition()\n\tconst [isSeeking, startSeekTransition] = useTransition()\n\n\t// Performance monitoring\n\tconst renderStartTime = React.useRef<number>(0)\n\tconst frameCount = React.useRef<number>(0)\n\tconst lastFrameTime = React.useRef<number>(0)\n\n\t// Throttled time update\n\tconst timeUpdateTimeoutRef = useRef<NodeJS.Timeout>()\n\tconst lastTimeUpdate = useRef<number>(0)\n\n\t// Store integration\n\tconst store = useMediaStore()\n\tconst isEnhanced = \"getOptimisticState\" in store\n\n\t// Select only the state we need to minimize re-renders\n\tconst isPlaying = useMediaSelector((state) => state.isPlaying)\n\tconst currentTime = useMediaSelector((state) => state.currentTime)\n\tconst duration = useMediaSelector((state) => state.duration)\n\tconst volume = useMediaSelector((state) => state.volume)\n\tconst isMuted = useMediaSelector((state) => state.isMuted)\n\tconst isLoading = useMediaSelector((state) => state.isLoading)\n\tconst isBuffering = useMediaSelector((state) => state.isBuffering)\n\tconst error = useMediaSelector((state) => state.error)\n\tconst buffered = useMediaSelector((state) => state.buffered)\n\tconst isFullscreen = useMediaSelector((state) => state.isFullscreen)\n\n\t// Enhanced features - always call hooks unconditionally\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\tconst optimisticState = useMediaOptimistic(enhancedStore)\n\tconst actions = useMediaActions(enhancedStore)\n\n\t// Performance state\n\tconst [performanceMetrics, setPerformanceMetrics] = React.useState({\n\t\tframeRate: 0,\n\t\taverageRenderTime: 0,\n\t\tdroppedFrames: 0,\n\t\tbufferHealth: 0\n\t})\n\n\t// Optimistic state updates for immediate UI feedback\n\tconst [optimisticVolume, setOptimisticVolume] = useOptimistic(\n\t\tvolume,\n\t\t(state, newVolume: number) => {\n\t\t\treturn Math.max(0, Math.min(1, newVolume))\n\t\t}\n\t)\n\n\tconst [optimisticTime, setOptimisticTime] = useOptimistic(\n\t\tcurrentTime,\n\t\t(state, newTime: number) => {\n\t\t\treturn Math.max(0, Math.min(duration || 0, newTime))\n\t\t}\n\t)\n\n\t// Initialize media element with performance optimizations\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Set initial properties\n\t\tconst initProps = {\n\t\t\tvolume: options.volume,\n\t\t\tmuted: options.muted,\n\t\t\tautoplay: options.autoPlay,\n\t\t\tloop: options.loop,\n\t\t\tpreload: options.preload,\n\t\t\tcrossOrigin: options.crossOrigin\n\t\t}\n\n\t\tObject.entries(initProps).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\t;(media as any)[key] = value\n\t\t\t}\n\t\t})\n\n\t\t// Performance optimizations\n\t\tmedia.setAttribute(\"preload\", options.preloadStrategy === \"eager\" ? \"auto\" : \"metadata\")\n\n\t\tif (options.bufferingStrategy === \"aggressive\") {\n\t\t\tmedia.setAttribute(\"buffered\", \"auto\")\n\t\t}\n\n\t\t// Hardware acceleration\n\t\tif (media instanceof HTMLVideoElement) {\n\t\t\tmedia.style.willChange = \"transform\"\n\t\t\tmedia.style.transform = \"translateZ(0)\"\n\t\t}\n\t}, [\n\t\toptions.volume,\n\t\toptions.muted,\n\t\toptions.autoPlay,\n\t\toptions.loop,\n\t\toptions.preload,\n\t\toptions.crossOrigin,\n\t\toptions.preloadStrategy,\n\t\toptions.bufferingStrategy\n\t])\n\n\t// Optimized event handlers with React 19 patterns\n\tconst handleTimeUpdate = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst now = performance.now()\n\n\t\t// Throttle time updates for performance\n\t\tif (options.enableTimeUpdateThrottling !== false) {\n\t\t\tif (now - lastTimeUpdate.current < (options.timeUpdateThrottleMs || 100)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlastTimeUpdate.current = now\n\t\t}\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setCurrentTime(media.currentTime)\n\t\t\t}\n\t\t})\n\t}, [options.enableTimeUpdateThrottling, options.timeUpdateThrottleMs, isEnhanced, actions])\n\n\tconst handlePlay = useCallback(() => {\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.play(true) // Optimistic update\n\t\t\t}\n\t\t})\n\t\toptions.onPlay?.()\n\t}, [isEnhanced, actions, options.onPlay])\n\n\tconst handlePause = useCallback(() => {\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.pause(true) // Optimistic update\n\t\t\t}\n\t\t})\n\t\toptions.onPause?.()\n\t}, [isEnhanced, actions, options.onPause])\n\n\tconst handleVolumeChange = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setVolume(media.volume, true) // Optimistic update\n\t\t\t\tmedia.muted ? actions.mute(true) : actions.unmute(true)\n\t\t\t}\n\t\t})\n\t}, [isEnhanced, actions])\n\n\tconst handleSeeking = useCallback(() => {\n\t\tstartSeekTransition(() => {\n\t\t\t// Seek operations get their own transition\n\t\t})\n\t}, [])\n\n\tconst handleSeeked = useCallback(() => {\n\t\t// Seek completed\n\t}, [])\n\n\tconst handleProgress = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setBuffered(media.buffered)\n\t\t\t}\n\t\t})\n\t}, [isEnhanced, actions])\n\n\t// Performance monitoring\n\tconst measureRenderTime = useCallback(() => {\n\t\tconst now = performance.now()\n\t\tconst deltaTime = now - lastFrameTime.current\n\n\t\tif (deltaTime > 0) {\n\t\t\tframeCount.current++\n\n\t\t\t// Calculate frame rate every second\n\t\t\tif (frameCount.current >= 60) {\n\t\t\t\tconst fps = Math.round((frameCount.current * 1000) / (now - lastFrameTime.current))\n\t\t\t\tsetPerformanceMetrics((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tframeRate: fps,\n\t\t\t\t\tdroppedFrames: Math.max(0, 60 - fps)\n\t\t\t\t}))\n\t\t\t\tframeCount.current = 0\n\t\t\t\tlastFrameTime.current = now\n\t\t\t}\n\t\t}\n\t}, [])\n\n\t// Attach event listeners with performance optimization\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Use passive listeners where possible for better performance\n\t\tconst eventListeners = [\n\t\t\t{ event: \"timeupdate\", handler: handleTimeUpdate, passive: true },\n\t\t\t{ event: \"play\", handler: handlePlay },\n\t\t\t{ event: \"pause\", handler: handlePause },\n\t\t\t{ event: \"volumechange\", handler: handleVolumeChange },\n\t\t\t{ event: \"seeking\", handler: handleSeeking },\n\t\t\t{ event: \"seeked\", handler: handleSeeked },\n\t\t\t{ event: \"progress\", handler: handleProgress, passive: true },\n\t\t\t{ event: \"loadedmetadata\", handler: () => measureRenderTime() },\n\t\t\t{ event: \"loadeddata\", handler: () => measureRenderTime() }\n\t\t]\n\n\t\teventListeners.forEach(({ event, handler, passive }) => {\n\t\t\tconst options = passive ? { passive: true } : {}\n\t\t\tmedia.addEventListener(event, handler, options)\n\t\t})\n\n\t\t// Performance monitoring frame loop\n\t\tlet rafId: number\n\t\tconst performanceLoop = () => {\n\t\t\tmeasureRenderTime()\n\t\t\trafId = requestAnimationFrame(performanceLoop)\n\t\t}\n\n\t\tif (options.enablePerformanceMonitoring) {\n\t\t\tperformanceLoop()\n\t\t}\n\n\t\treturn () => {\n\t\t\teventListeners.forEach(({ event, handler }) => {\n\t\t\t\tmedia.removeEventListener(event, handler)\n\t\t\t})\n\t\t\tif (rafId) {\n\t\t\t\tcancelAnimationFrame(rafId)\n\t\t\t}\n\t\t}\n\t}, [\n\t\thandleTimeUpdate,\n\t\thandlePlay,\n\t\thandlePause,\n\t\thandleVolumeChange,\n\t\thandleSeeking,\n\t\thandleSeeked,\n\t\thandleProgress,\n\t\tmeasureRenderTime,\n\t\toptions.enablePerformanceMonitoring\n\t])\n\n\t// Optimized control functions with React 19 features\n\tconst controls = useMemo(() => {\n\t\tconst play = async () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tawait actions.play(true) // Optimistic\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tawait media.play()\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to play media:\", error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst pause = () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.pause(true) // Optimistic\n\t\t\t} else {\n\t\t\t\tmedia.pause()\n\t\t\t}\n\t\t}\n\n\t\tconst toggle = () => {\n\t\t\tif (isPlaying) {\n\t\t\t\tpause()\n\t\t\t} else {\n\t\t\t\tplay()\n\t\t\t}\n\t\t}\n\n\t\tconst seek = (time: number) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tconst clampedTime = Math.max(0, Math.min(time, duration || 0))\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tstartSeekTransition(() => {\n\t\t\t\t\tactions.seek(clampedTime, true) // Optimistic\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tmedia.currentTime = clampedTime\n\t\t\t}\n\t\t}\n\n\t\tconst setVolume = (volume: number) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tconst clampedVolume = Math.max(0, Math.min(1, volume))\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tsetOptimisticVolume(clampedVolume)\n\t\t\t\tstartTransition(() => {\n\t\t\t\t\tactions.setVolume(clampedVolume, true)\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tmedia.volume = clampedVolume\n\t\t\t}\n\t\t}\n\n\t\tconst toggleMute = () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.toggleMute(true) // Optimistic\n\t\t\t} else {\n\t\t\t\tmedia.muted = !media.muted\n\t\t\t}\n\t\t}\n\n\t\tconst enterFullscreen = async () => {\n\t\t\tconst container = containerRef.current\n\t\t\tif (!container || !document.fullscreenEnabled) return\n\n\t\t\ttry {\n\t\t\t\tawait container.requestFullscreen()\n\t\t\t\tif (isEnhanced && actions) {\n\t\t\t\t\tactions.enterFullscreen(true)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to enter fullscreen:\", error)\n\t\t\t}\n\t\t}\n\n\t\tconst exitFullscreen = async () => {\n\t\t\tif (!document.fullscreenElement) return\n\n\t\t\ttry {\n\t\t\t\tawait document.exitFullscreen()\n\t\t\t\tif (isEnhanced && actions) {\n\t\t\t\t\tactions.exitFullscreen(true)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to exit fullscreen:\", error)\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tplay,\n\t\t\tpause,\n\t\t\ttoggle,\n\t\t\tseek,\n\t\t\tsetVolume,\n\t\t\ttoggleMute,\n\t\t\tenterFullscreen,\n\t\t\texitFullscreen\n\t\t}\n\t}, [\n\t\tisPlaying,\n\t\tduration,\n\t\tisEnhanced,\n\t\tactions,\n\t\tstartTransition,\n\t\tstartSeekTransition,\n\t\tsetOptimisticVolume\n\t])\n\n\t// Computed state\n\tconst computedState = useMemo(\n\t\t() => ({\n\t\t\tisPlaying: optimisticState?.isPlaying ?? isPlaying,\n\t\t\tcurrentTime: optimisticState?.currentTime ?? currentTime,\n\t\t\tduration: optimisticState?.duration ?? duration,\n\t\t\tvolume: optimisticState?.volume ?? optimisticVolume,\n\t\t\tisMuted: optimisticState?.isMuted ?? isMuted,\n\t\t\tisLoading: optimisticState?.isBuffering ?? isLoading,\n\t\t\tisBuffering: optimisticState?.isBuffering ?? isBuffering,\n\t\t\terror: optimisticState?.error ?? error,\n\t\t\tbuffered: optimisticState?.buffered ?? buffered,\n\t\t\tisFullscreen: optimisticState?.isFullscreen ?? isFullscreen,\n\t\t\tprogress: duration > 0 ? currentTime / duration : 0,\n\t\t\tisTransitioning: isPending || isSeeking,\n\t\t\tcanPlay: !isLoading && !isBuffering && !error\n\t\t}),\n\t\t[\n\t\t\toptimisticState,\n\t\t\tisPlaying,\n\t\t\tcurrentTime,\n\t\t\tduration,\n\t\t\toptimisticVolume,\n\t\t\tisMuted,\n\t\t\tisLoading,\n\t\t\tisBuffering,\n\t\t\terror,\n\t\t\tbuffered,\n\t\t\tisFullscreen,\n\t\t\tisPending,\n\t\t\tisSeeking\n\t\t]\n\t)\n\n\treturn {\n\t\t// Refs\n\t\tmediaRef,\n\t\tcontainerRef,\n\n\t\t// State\n\t\tstate: computedState,\n\t\tactualState: optimisticState?.actualState,\n\n\t\t// Controls\n\t\tcontrols,\n\n\t\t// Performance metrics\n\t\tperformanceMetrics,\n\t\tisTransitioning: isPending || isSeeking,\n\n\t\t// Enhanced features\n\t\tactions: optimisticState?.actions,\n\t\tactionState: optimisticState?.actionState,\n\n\t\t// Optimistic features\n\t\toptimisticState,\n\t\tisEnhanced\n\t}\n}\n","\"use client\"\n\nimport { useCallback, useEffect } from \"react\"\nimport type { MediaPlayerControls, MediaPlayerState } from \"../types/index\"\n\ninterface UseKeyboardControlsOptions {\n\tenabled?: boolean\n\tstate: MediaPlayerState\n\tcontrols: MediaPlayerControls\n\tseekStep?: number // seconds to seek forward/backward\n\tvolumeStep?: number // volume step (0-1)\n}\n\nexport function useKeyboardControls({\n\tenabled = true,\n\tstate,\n\tcontrols,\n\tseekStep = 10,\n\tvolumeStep = 0.1\n}: UseKeyboardControlsOptions) {\n\tconst handleKeyDown = (event: KeyboardEvent) => {\n\t\tif (!enabled) return\n\n\t\t// Don't handle keyboard events if user is typing in an input\n\t\tconst target = event.target as HTMLElement\n\t\tif (\n\t\t\ttarget.tagName === \"INPUT\" ||\n\t\t\ttarget.tagName === \"TEXTAREA\" ||\n\t\t\ttarget.contentEditable === \"true\"\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tswitch (event.code) {\n\t\t\tcase \"Space\":\n\t\t\tcase \"KeyK\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggle()\n\t\t\t\tbreak\n\n\t\t\tcase \"KeyM\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggleMute()\n\t\t\t\tbreak\n\n\t\t\tcase \"KeyF\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggleFullscreen()\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(Math.max(0, state.currentTime - seekStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(Math.min(state.duration, state.currentTime + seekStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.setVolume(Math.min(1, state.volume + volumeStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.setVolume(Math.max(0, state.volume - volumeStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"Digit0\":\n\t\t\tcase \"Digit1\":\n\t\t\tcase \"Digit2\":\n\t\t\tcase \"Digit3\":\n\t\t\tcase \"Digit4\":\n\t\t\tcase \"Digit5\":\n\t\t\tcase \"Digit6\":\n\t\t\tcase \"Digit7\":\n\t\t\tcase \"Digit8\":\n\t\t\tcase \"Digit9\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst digit = parseInt(event.code.replace(\"Digit\", \"\"), 10)\n\t\t\t\tconst percentage = digit / 10\n\t\t\t\tcontrols.seek(state.duration * percentage)\n\t\t\t\tbreak\n\n\t\t\tcase \"Home\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(0)\n\t\t\t\tbreak\n\n\t\t\tcase \"End\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(state.duration)\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\t// Don't prevent default for unhandled keys\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tif (!enabled) return\n\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyDown)\n\t\t}\n\t}, [enabled, handleKeyDown])\n\n\treturn {\n\t\thandleKeyDown\n\t}\n}\n","\"use client\"\n\nimport React, { useEffect, useRef, useCallback, useMemo } from \"react\"\n\n// Memory optimization hook for media players\nexport function useMemoryOptimization(\n\toptions: {\n\t\tmaxMemoryUsage?: number // in MB\n\t\tcleanupInterval?: number // in ms\n\t\tenableGC?: boolean\n\t\tmonitorMemory?: boolean\n\t} = {}\n) {\n\tconst {\n\t\tmaxMemoryUsage = 100, // 100MB default\n\t\tcleanupInterval = 30000, // 30 seconds default\n\t\tenableGC = true,\n\t\tmonitorMemory = true\n\t} = options\n\n\tconst cleanupTimeoutRef = useRef<NodeJS.Timeout>()\n\tconst observersRef = useRef<Set<MutationObserver>>(new Set())\n\tconst eventListenersRef = useRef<Map<Element, Array<{ event: string; handler: EventListener }>>>(\n\t\tnew Map()\n\t)\n\tconst intervalRefs = useRef<Set<NodeJS.Timeout>>(new Set())\n\tconst animationFrameRefs = useRef<Set<number>>(new Set())\n\n\t// Get current memory usage\n\tconst getMemoryUsage = useCallback(() => {\n\t\tif (typeof window === \"undefined\" || !(\"memory\" in performance)) {\n\t\t\treturn { used: 0, total: 0, limit: 0 }\n\t\t}\n\n\t\tconst memory = (performance as any).memory\n\t\treturn {\n\t\t\tused: memory.usedJSHeapSize,\n\t\t\ttotal: memory.totalJSHeapSize,\n\t\t\tlimit: memory.jsHeapSizeLimit\n\t\t}\n\t}, [])\n\n\t// Memory monitoring state\n\tconst [memoryStats, setMemoryStats] = React.useState({\n\t\tused: 0,\n\t\ttotal: 0,\n\t\tlimit: 0,\n\t\tusage: 0,\n\t\tisHighUsage: false\n\t})\n\n\t// Cleanup function (must be declared before use)\n\tconst performCleanup = useCallback(() => {\n\t\t// Clear all timeouts\n\t\tintervalRefs.current.forEach((timeout) => {\n\t\t\tclearTimeout(timeout)\n\t\t})\n\t\tintervalRefs.current.clear()\n\n\t\t// Cancel all animation frames\n\t\tanimationFrameRefs.current.forEach((frameId) => {\n\t\t\tcancelAnimationFrame(frameId)\n\t\t})\n\t\tanimationFrameRefs.current.clear()\n\n\t\t// Disconnect all observers\n\t\tobserversRef.current.forEach((observer) => {\n\t\t\tobserver.disconnect()\n\t\t})\n\t\tobserversRef.current.clear()\n\n\t\t// Remove all event listeners\n\t\teventListenersRef.current.forEach((listeners, element) => {\n\t\t\tlisteners.forEach(({ event, handler }) => {\n\t\t\t\telement.removeEventListener(event, handler)\n\t\t\t})\n\t\t})\n\t\teventListenersRef.current.clear()\n\n\t\t// Force garbage collection if available\n\t\tif (typeof window !== \"undefined\" && \"gc\" in window) {\n\t\t\t;(window as any).gc()\n\t\t}\n\t}, [])\n\n\t// Safe interval management (must be declared before use)\n\tconst useInterval = useCallback((callback: () => void, delay: number) => {\n\t\tconst timeoutId = setInterval(callback, delay)\n\t\tintervalRefs.current.add(timeoutId)\n\n\t\treturn () => {\n\t\t\tclearInterval(timeoutId)\n\t\t\tintervalRefs.current.delete(timeoutId)\n\t\t}\n\t}, [])\n\n\t// Memory monitoring\n\tuseEffect(() => {\n\t\tif (!monitorMemory) return\n\n\t\tconst checkMemory = () => {\n\t\t\tconst memory = getMemoryUsage()\n\t\t\tconst usage = memory.used / 1024 / 1024 // Convert to MB\n\t\t\tconst isHighUsage = usage > maxMemoryUsage\n\n\t\t\tsetMemoryStats({\n\t\t\t\t...memory,\n\t\t\t\tusage,\n\t\t\t\tisHighUsage\n\t\t\t})\n\n\t\t\t// Trigger cleanup if memory usage is high\n\t\t\tif (isHighUsage && enableGC) {\n\t\t\t\tperformCleanup()\n\t\t\t}\n\t\t}\n\n\t\tcheckMemory()\n\t\treturn useInterval(checkMemory, cleanupInterval)\n\t}, [monitorMemory, getMemoryUsage, maxMemoryUsage, enableGC, cleanupInterval, performCleanup])\n\n\t// Safe event listener management\n\tconst addEventListener = useCallback(\n\t\t(\n\t\t\telement: Element,\n\t\t\tevent: string,\n\t\t\thandler: EventListener,\n\t\t\toptions?: AddEventListenerOptions\n\t\t) => {\n\t\t\telement.addEventListener(event, handler, options)\n\n\t\t\tif (!eventListenersRef.current.has(element)) {\n\t\t\t\teventListenersRef.current.set(element, [])\n\t\t\t}\n\t\t\teventListenersRef.current.get(element)!.push({ event, handler })\n\n\t\t\t// Return cleanup function\n\t\t\treturn () => {\n\t\t\t\telement.removeEventListener(event, handler)\n\t\t\t\tconst listeners = eventListenersRef.current.get(element)\n\t\t\t\tif (listeners) {\n\t\t\t\t\tconst index = listeners.findIndex((l) => l.event === event && l.handler === handler)\n\t\t\t\t\tif (index > -1) {\n\t\t\t\t\t\tlisteners.splice(index, 1)\n\t\t\t\t\t}\n\t\t\t\t\tif (listeners.length === 0) {\n\t\t\t\t\t\teventListenersRef.current.delete(element)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\t// Safe timeout management\n\tconst setTimeout = useCallback((callback: () => void, delay: number) => {\n\t\tconst timeoutId = setTimeout(callback, delay)\n\t\tintervalRefs.current.add(timeoutId)\n\n\t\treturn () => {\n\t\t\tclearTimeout(timeoutId)\n\t\t\tintervalRefs.current.delete(timeoutId)\n\t\t}\n\t}, [])\n\n\t// Safe animation frame management\n\tconst requestAnimationFrame = useCallback((callback: FrameRequestCallback) => {\n\t\tconst frameId = requestAnimationFrame(callback)\n\t\tanimationFrameRefs.current.add(frameId)\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(frameId)\n\t\t\tanimationFrameRefs.current.delete(frameId)\n\t\t}\n\t}, [])\n\n\t// Safe observer management\n\tconst addObserver = useCallback((observer: MutationObserver) => {\n\t\tobserversRef.current.add(observer)\n\n\t\treturn () => {\n\t\t\tobserver.disconnect()\n\t\t\tobserversRef.current.delete(observer)\n\t\t}\n\t}, [])\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tperformCleanup()\n\t\t}\n\t}, [performCleanup])\n\n\treturn {\n\t\t// Memory stats\n\t\tmemoryStats,\n\t\tgetMemoryUsage,\n\n\t\t// Cleanup functions\n\t\tperformCleanup,\n\n\t\t// Safe API functions\n\t\taddEventListener,\n\t\tsetInterval,\n\t\tsetTimeout,\n\t\trequestAnimationFrame,\n\t\taddObserver,\n\n\t\t// Utilities\n\t\tformatBytes: (bytes: number) => {\n\t\t\tif (bytes === 0) return \"0 Bytes\"\n\t\t\tconst k = 1024\n\t\t\tconst sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"]\n\t\t\tconst i = Math.floor(Math.log(bytes) / Math.log(k))\n\t\t\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i]\n\t\t}\n\t}\n}\n\n// Resource cleanup hook for media elements\nexport function useMediaResourceCleanup(\n\tmediaRef: React.RefObject<HTMLVideoElement | HTMLAudioElement>\n) {\n\tconst { addEventListener, performCleanup } = useMemoryOptimization()\n\n\t// Track resource cleanup\n\tconst cleanupResources = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Stop media playback\n\t\tif (!media.paused) {\n\t\t\t_media.pause()\n\t\t}\n\n\t\t// Clear source\n\t\tif (media.src) {\n\t\t\tmedia.src = \"\"\n\t\t\tmedia.load()\n\t\t}\n\n\t\t// Remove source elements\n\t\twhile (media.firstChild) {\n\t\t\tmedia.removeChild(media.firstChild)\n\t\t}\n\n\t\t// Clear any pending seeks\n\t\tmedia.currentTime = 0\n\n\t\t// Clear buffered data\n\t\tif (\"clearBuffered\" in media) {\n\t\t\t;(media as any).clearBuffered()\n\t\t}\n\t}, [mediaRef])\n\n\t// Enhanced event listener registration\n\tconst registerMediaEventListener = useCallback(\n\t\t(event: string, handler: EventListener, options?: AddEventListenerOptions) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return () => {}\n\n\t\t\treturn addEventListener(media, event, handler, options)\n\t\t},\n\t\t[mediaRef, addEventListener]\n\t)\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn cleanupResources\n\t}, [cleanupResources])\n\n\treturn {\n\t\tcleanupResources,\n\t\tregisterMediaEventListener\n\t}\n}\n\n// Performance monitoring hook\nexport function usePerformanceMonitoring() {\n\tconst [metrics, setMetrics] = React.useState({\n\t\tfps: 0,\n\t\tframeDrops: 0,\n\t\tlongTasks: 0,\n\t\ttotalLongTaskDuration: 0\n\t})\n\n\tconst frameCountRef = useRef(0)\n\tconst lastFrameTimeRef = useRef(performance.now())\n\tconst longTaskObserverRef = useRef<PerformanceObserver>()\n\n\t// FPS monitoring\n\tuseEffect(() => {\n\t\tlet rafId: number\n\n\t\tconst measureFrame = () => {\n\t\t\tframeCountRef.current++\n\t\t\tconst now = performance.now()\n\n\t\t\t// Calculate FPS every second\n\t\t\tif (now - lastFrameTimeRef.current >= 1000) {\n\t\t\t\tconst fps = Math.round((frameCountRef.current * 1000) / (now - lastFrameTimeRef.current))\n\t\t\t\tconst expectedFrames = Math.round((now - lastFrameTimeRef.current) / 16.67) // 60fps\n\t\t\t\tconst frameDrops = Math.max(0, expectedFrames - frameCountRef.current)\n\n\t\t\t\tsetMetrics((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tfps,\n\t\t\t\t\tframeDrops: prev.frameDrops + frameDrops\n\t\t\t\t}))\n\n\t\t\t\tframeCountRef.current = 0\n\t\t\t\tlastFrameTimeRef.current = now\n\t\t\t}\n\n\t\t\trafId = requestAnimationFrame(measureFrame)\n\t\t}\n\n\t\trafId = requestAnimationFrame(measureFrame)\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(rafId)\n\t\t}\n\t}, [])\n\n\t// Long task monitoring\n\tuseEffect(() => {\n\t\tif (!(\"PerformanceObserver\" in window)) return\n\n\t\ttry {\n\t\t\tconst observer = new PerformanceObserver((list) => {\n\t\t\t\tfor (const entry of list.getEntries()) {\n\t\t\t\t\tif (entry.duration > 50) {\n\t\t\t\t\t\t// Long task threshold\n\t\t\t\t\t\tsetMetrics((prev) => ({\n\t\t\t\t\t\t\t...prev,\n\t\t\t\t\t\t\tlongTasks: prev.longTasks + 1,\n\t\t\t\t\t\t\ttotalLongTaskDuration: prev.totalLongTaskDuration + entry.duration\n\t\t\t\t\t\t}))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tobserver.observe({ entryTypes: [\"longtask\"] })\n\t\t\tlongTaskObserverRef.current = observer\n\n\t\t\treturn () => {\n\t\t\t\tobserver.disconnect()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Long task monitoring not supported:\", error)\n\t\t}\n\t}, [])\n\n\treturn {\n\t\t...metrics,\n\t\taverageLongTaskDuration:\n\t\t\tmetrics.longTasks > 0 ? metrics.totalLongTaskDuration / metrics.longTasks : 0,\n\t\tisPerformanceGood: metrics.fps >= 50 && metrics.frameDrops < 5\n\t}\n}\n","\"use client\"\n\nimport { useActionState, useCallback, useOptimistic, useState } from \"react\"\nimport { useMediaSelector, useMediaStore } from \"../context/media-context\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\nimport type { MediaPlayerState } from \"../types/index\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\n\n// Legacy hook for backward compatibility\nexport function useMediaState() {\n\tconst [state, setState] = useState<MediaPlayerState>({\n\t\tisPlaying: false,\n\t\tcurrentTime: 0,\n\t\tduration: 0,\n\t\tvolume: 1,\n\t\tisMuted: false,\n\t\tisLoading: false,\n\t\tisFullscreen: false,\n\t\terror: null,\n\t\tbuffered: null\n\t})\n\n\tconst updateState = (updates: Partial<MediaPlayerState>) => {\n\t\tsetState((prev: MediaPlayerState) => ({ ...prev, ...updates }))\n\t}\n\n\tconst setPlaying = (isPlaying: boolean) => {\n\t\tupdateState({ isPlaying })\n\t}\n\n\tconst setCurrentTime = (currentTime: number) => {\n\t\tupdateState({ currentTime })\n\t}\n\n\tconst setDuration = (duration: number) => {\n\t\tupdateState({ duration })\n\t}\n\n\tconst setVolume = (volume: number) => {\n\t\tupdateState({ volume: Math.max(0, Math.min(1, volume)) })\n\t}\n\n\tconst setMuted = (isMuted: boolean) => {\n\t\tupdateState({ isMuted })\n\t}\n\n\tconst setLoading = (isLoading: boolean) => {\n\t\tupdateState({ isLoading })\n\t}\n\n\tconst setFullscreen = (isFullscreen: boolean) => {\n\t\tupdateState({ isFullscreen })\n\t}\n\n\tconst setError = (error: string | null) => {\n\t\tupdateState({ error })\n\t}\n\n\tconst setBuffered = (buffered: TimeRanges | null) => {\n\t\tupdateState({ buffered })\n\t}\n\n\treturn {\n\t\tstate,\n\t\tupdateState,\n\t\tsetPlaying,\n\t\tsetCurrentTime,\n\t\tsetDuration,\n\t\tsetVolume,\n\t\tsetMuted,\n\t\tsetLoading,\n\t\tsetFullscreen,\n\t\tsetError,\n\t\tsetBuffered\n\t}\n}\n\n// React 19 enhanced media state hook\nexport function useEnhancedMediaState() {\n\tconst store = useMediaStore()\n\n\t// Check if this is an enhanced store\n\tconst isEnhanced = \"getOptimisticState\" in store\n\n\t// Always call hooks unconditionally\n\tconst regularState = useMediaState()\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\tconst optimisticState = useMediaOptimistic(enhancedStore)\n\tconst actions = useMediaActions(enhancedStore)\n\n\t// Return appropriate state based on store type\n\tif (!isEnhanced) {\n\t\t// Fall back to regular media state if not enhanced\n\t\treturn regularState as any\n\t}\n\n\treturn {\n\t\t// State (optimistic values for immediate UI feedback)\n\t\tstate: optimisticState.state,\n\t\tactualState: optimisticState.actualState,\n\n\t\t// Individual state selectors\n\t\tisPlaying: optimisticState.isPlaying,\n\t\tcurrentTime: optimisticState.currentTime,\n\t\tduration: optimisticState.state.duration,\n\t\tvolume: optimisticState.volume,\n\t\tisMuted: optimisticState.isMuted,\n\t\tisLoading: optimisticState.isBuffering,\n\t\tisFullscreen: optimisticState.isFullscreen,\n\t\terror: optimisticState.state.error,\n\t\tbuffered: optimisticState.state.buffered,\n\n\t\t// Computed values\n\t\tprogress: optimisticState.progress,\n\t\tformattedTime: optimisticState.formattedTime,\n\t\tformattedDuration: optimisticState.formattedDuration,\n\n\t\t// Actions with optimistic updates\n\t\tactions,\n\n\t\t// Action state for loading/error handling\n\t\tisActionLoading: actions.isLoading,\n\t\tactionError: actions.errorMessage,\n\t\tretryLastAction: actions.retryLastAction,\n\n\t\t// Legacy compatibility methods\n\t\tupdateState: (updates: Partial<MediaPlayerState>) => {\n\t\t\t// Map legacy updates to new actions\n\t\t\tif (\"isPlaying\" in updates) {\n\t\t\t\tupdates.isPlaying ? actions.play() : actions.pause()\n\t\t\t}\n\t\t\tif (\"currentTime\" in updates) {\n\t\t\t\tactions.setCurrentTime(updates.currentTime!)\n\t\t\t}\n\t\t\tif (\"duration\" in updates) {\n\t\t\t\tactions.setDuration(updates.duration!)\n\t\t\t}\n\t\t\tif (\"volume\" in updates) {\n\t\t\t\tactions.setVolume(updates.volume!)\n\t\t\t}\n\t\t\tif (\"isMuted\" in updates) {\n\t\t\t\tupdates.isMuted ? actions.mute() : actions.unmute()\n\t\t\t}\n\t\t\tif (\"isLoading\" in updates) {\n\t\t\t\tactions.setLoading(updates.isLoading!)\n\t\t\t}\n\t\t\tif (\"isFullscreen\" in updates) {\n\t\t\t\tupdates.isFullscreen ? actions.enterFullscreen() : actions.exitFullscreen()\n\t\t\t}\n\t\t\tif (\"error\" in updates) {\n\t\t\t\tactions.setError(updates.error ?? null)\n\t\t\t}\n\t\t\tif (\"buffered\" in updates) {\n\t\t\t\tactions.setBuffered(updates.buffered ?? null)\n\t\t\t}\n\t\t},\n\n\t\t// Individual action methods for legacy compatibility\n\t\tsetPlaying: (isPlaying: boolean) => {\n\t\t\tisPlaying ? actions.play(true) : actions.pause(true) // Use optimistic updates\n\t\t},\n\t\tsetCurrentTime: (time: number) => actions.setCurrentTime(time),\n\t\tsetDuration: (duration: number) => actions.setDuration(duration),\n\t\tsetVolume: (volume: number) => actions.setVolume(volume, true),\n\t\tsetMuted: (muted: boolean) => {\n\t\t\tmuted ? actions.mute(true) : actions.unmute(true)\n\t\t},\n\t\tsetLoading: (loading: boolean) => actions.setLoading(loading),\n\t\tsetFullscreen: (fullscreen: boolean) => {\n\t\t\tfullscreen ? actions.enterFullscreen(true) : actions.exitFullscreen(true)\n\t\t},\n\t\tsetError: (error: string | null) => actions.setError(error),\n\t\tsetBuffered: (buffered: TimeRanges | null) => actions.setBuffered(buffered)\n\t}\n}\n\n// Hook that automatically chooses between legacy and enhanced based on context availability\nexport function useAdaptiveMediaState() {\n\t// Always call hooks unconditionally\n\tconst enhancedState = useEnhancedMediaState()\n\tconst regularState = useMediaState()\n\n\t// Check if we're in an enhanced context by testing a property that would only exist in enhanced mode\n\tconst isEnhancedContext = \"getOptimisticState\" in enhancedState\n\n\tif (!isEnhancedContext) {\n\t\t// Fall back to legacy version if not in MediaProvider context\n\t\tconsole.warn(\"MediaStore context not available, using legacy state management\")\n\t\treturn regularState\n\t}\n\n\treturn enhancedState\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useRef } from \"react\"\nimport type { MediaPlayerControls } from \"../types/index\"\nimport { useMediaState } from \"./use-media-state\"\n\ninterface UseMediaPlayerOptions {\n\tsrc: string | string[]\n\tautoPlay?: boolean\n\tloop?: boolean\n\tmuted?: boolean\n\tvolume?: number\n\tpreload?: \"none\" | \"metadata\" | \"auto\"\n\tcrossOrigin?: \"anonymous\" | \"use-credentials\"\n\tplaybackRates?: number[]\n\tkeyboardControls?: boolean\n\tshowControls?: boolean\n\tcustomControls?: boolean\n\tonPlay?: () => void\n\tonPause?: () => void\n\tonTimeUpdate?: (currentTime: number) => void\n\tonDurationChange?: (duration: number) => void\n\tonVolumeChange?: (volume: number) => void\n\tonError?: (error: string) => void\n\tonLoadStart?: () => void\n\tonLoadedData?: () => void\n\tonEnded?: () => void\n}\n\nexport function useMediaPlayer(options: UseMediaPlayerOptions) {\n\tconst mediaRef = useRef<HTMLVideoElement | HTMLAudioElement>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\n\tconst {\n\t\tstate,\n\t\tsetPlaying,\n\t\tsetCurrentTime,\n\t\tsetDuration,\n\t\tsetVolume,\n\t\tsetMuted,\n\t\tsetLoading,\n\t\tsetFullscreen,\n\t\tsetError,\n\t\tsetBuffered\n\t} = useMediaState()\n\n\t// Initialize media element with options\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Set initial properties\n\t\tif (options.volume !== undefined) {\n\t\t\tmedia.volume = options.volume\n\t\t\tsetVolume(options.volume)\n\t\t}\n\t\tif (options.muted !== undefined) {\n\t\t\tmedia.muted = options.muted\n\t\t\tsetMuted(options.muted)\n\t\t}\n\t\tif (options.autoPlay !== undefined) {\n\t\t\tmedia.autoplay = options.autoPlay\n\t\t}\n\t\tif (options.loop !== undefined) {\n\t\t\tmedia.loop = options.loop\n\t\t}\n\t\tif (options.preload !== undefined) {\n\t\t\tmedia.preload = options.preload\n\t\t}\n\t\tif (options.crossOrigin !== undefined) {\n\t\t\tmedia.crossOrigin = options.crossOrigin\n\t\t}\n\t}, [options, setVolume, setMuted])\n\n\t// Event handlers\n\tconst handlePlay = () => {\n\t\tsetPlaying(true)\n\t\toptions.onPlay?.()\n\t}\n\n\tconst handlePause = () => {\n\t\tsetPlaying(false)\n\t\toptions.onPause?.()\n\t}\n\n\tconst handleTimeUpdate = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetCurrentTime(media.currentTime)\n\t\toptions.onTimeUpdate?.(media.currentTime)\n\t}\n\n\tconst handleDurationChange = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetDuration(media.duration)\n\t\toptions.onDurationChange?.(media.duration)\n\t}\n\n\tconst handleVolumeChange = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetVolume(media.volume)\n\t\tsetMuted(media.muted)\n\t\toptions.onVolumeChange?.(media.volume)\n\t}\n\n\tconst handleLoadStart = () => {\n\t\tsetLoading(true)\n\t\tsetError(null)\n\t\toptions.onLoadStart?.()\n\t}\n\n\tconst handleLoadedData = () => {\n\t\tsetLoading(false)\n\t\toptions.onLoadedData?.()\n\t}\n\n\tconst handleError = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst errorMessage = media.error?.message || \"An error occurred while loading the media\"\n\t\tsetError(errorMessage)\n\t\tsetLoading(false)\n\t\toptions.onError?.(errorMessage)\n\t}\n\n\tconst handleEnded = () => {\n\t\tsetPlaying(false)\n\t\toptions.onEnded?.()\n\t}\n\n\tconst handleProgress = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetBuffered(media.buffered)\n\t}\n\n\t// Attach event listeners\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.addEventListener(\"play\", handlePlay)\n\t\tmedia.addEventListener(\"pause\", handlePause)\n\t\tmedia.addEventListener(\"timeupdate\", handleTimeUpdate)\n\t\tmedia.addEventListener(\"durationchange\", handleDurationChange)\n\t\tmedia.addEventListener(\"volumechange\", handleVolumeChange)\n\t\tmedia.addEventListener(\"loadstart\", handleLoadStart)\n\t\tmedia.addEventListener(\"loadeddata\", handleLoadedData)\n\t\tmedia.addEventListener(\"error\", handleError)\n\t\tmedia.addEventListener(\"ended\", handleEnded)\n\t\tmedia.addEventListener(\"progress\", handleProgress)\n\n\t\treturn () => {\n\t\t\tmedia.removeEventListener(\"play\", handlePlay)\n\t\t\tmedia.removeEventListener(\"pause\", handlePause)\n\t\t\tmedia.removeEventListener(\"timeupdate\", handleTimeUpdate)\n\t\t\tmedia.removeEventListener(\"durationchange\", handleDurationChange)\n\t\t\tmedia.removeEventListener(\"volumechange\", handleVolumeChange)\n\t\t\tmedia.removeEventListener(\"loadstart\", handleLoadStart)\n\t\t\tmedia.removeEventListener(\"loadeddata\", handleLoadedData)\n\t\t\tmedia.removeEventListener(\"error\", handleError)\n\t\t\tmedia.removeEventListener(\"ended\", handleEnded)\n\t\t\tmedia.removeEventListener(\"progress\", handleProgress)\n\t\t}\n\t}, [\n\t\thandlePlay,\n\t\thandlePause,\n\t\thandleTimeUpdate,\n\t\thandleDurationChange,\n\t\thandleVolumeChange,\n\t\thandleLoadStart,\n\t\thandleLoadedData,\n\t\thandleError,\n\t\thandleEnded,\n\t\thandleProgress\n\t])\n\n\t// Control functions\n\tconst play = async () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\ttry {\n\t\t\tawait media.play()\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to play media:\", error)\n\t\t\tsetError(\"Failed to play media\")\n\t\t}\n\t}\n\n\tconst pause = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.pause()\n\t}\n\n\tconst toggle = () => {\n\t\tif (state.isPlaying) {\n\t\t\tpause()\n\t\t} else {\n\t\t\tplay()\n\t\t}\n\t}\n\n\tconst seek = (time: number) => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.currentTime = Math.max(0, Math.min(time, media.duration || 0))\n\t}\n\n\tconst setVolumeControl = (volume: number) => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst clampedVolume = Math.max(0, Math.min(1, volume))\n\t\tmedia.volume = clampedVolume\n\t}\n\n\tconst mute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = true\n\t}\n\n\tconst unmute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = false\n\t}\n\n\tconst toggleMute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = !media.muted\n\t}\n\n\tconst enterFullscreen = async () => {\n\t\tconst container = containerRef.current\n\t\tif (!container || !document.fullscreenEnabled) return\n\n\t\ttry {\n\t\t\tawait container.requestFullscreen()\n\t\t\tsetFullscreen(true)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to enter fullscreen:\", error)\n\t\t}\n\t}\n\n\tconst exitFullscreen = async () => {\n\t\tif (!document.fullscreenElement) return\n\n\t\ttry {\n\t\t\tawait document.exitFullscreen()\n\t\t\tsetFullscreen(false)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to exit fullscreen:\", error)\n\t\t}\n\t}\n\n\tconst toggleFullscreen = () => {\n\t\tif (document.fullscreenElement) {\n\t\t\texitFullscreen()\n\t\t} else {\n\t\t\tenterFullscreen()\n\t\t}\n\t}\n\n\t// Listen for fullscreen changes\n\tuseEffect(() => {\n\t\tconst handleFullscreenChange = () => {\n\t\t\tsetFullscreen(!!document.fullscreenElement)\n\t\t}\n\n\t\tdocument.addEventListener(\"fullscreenchange\", handleFullscreenChange)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"fullscreenchange\", handleFullscreenChange)\n\t\t}\n\t}, [setFullscreen])\n\n\tconst controls: MediaPlayerControls = {\n\t\tplay,\n\t\tpause,\n\t\ttoggle,\n\t\tseek,\n\t\tsetVolume: setVolumeControl,\n\t\tmute,\n\t\tunmute,\n\t\ttoggleMute,\n\t\tenterFullscreen,\n\t\texitFullscreen,\n\t\ttoggleFullscreen\n\t}\n\n\treturn {\n\t\tstate,\n\t\tcontrols,\n\t\tmediaRef,\n\t\tcontainerRef\n\t}\n}\n","import * as React from \"react\"\n\n// Mobile breakpoints following mobile-first approach\nconst BREAKPOINTS = {\n mobile: 768,\n tablet: 1024,\n desktop: 1280\n} as const\n\n// Device detection utilities\nfunction detectPlatform(): 'ios' | 'android' | 'desktop' | 'unknown' {\n if (typeof window === 'undefined') return 'unknown'\n \n const userAgent = window.navigator.userAgent.toLowerCase()\n \n if (/iphone|ipad|ipod/.test(userAgent)) return 'ios'\n if (/android/.test(userAgent)) return 'android'\n if (/windows|mac|linux/.test(userAgent)) return 'desktop'\n \n return 'unknown'\n}\n\nfunction isTouchDevice(): boolean {\n if (typeof window === 'undefined') return false\n \n return (\n 'ontouchstart' in window ||\n navigator.maxTouchPoints > 0 ||\n // @ts-ignore - for older browsers\n navigator.msMaxTouchPoints > 0\n )\n}\n\nfunction supportsHaptics(): boolean {\n if (typeof window === 'undefined') return false\n \n // Check for haptic feedback support\n return (\n 'vibrate' in navigator ||\n // @ts-ignore - for newer Vibration API\n 'vibration' in navigator ||\n // @ts-ignore - for iOS haptic feedback\n 'ondevicemotion' in window\n )\n}\n\n// Enhanced device information interface\nexport interface DeviceInfo {\n isMobile: boolean\n isTablet: boolean\n isDesktop: boolean\n isTouchDevice: boolean\n platform: 'ios' | 'android' | 'desktop' | 'unknown'\n supportsHaptics: boolean\n screenSize: {\n width: number\n height: number\n }\n orientation: 'portrait' | 'landscape'\n}\n\n// Legacy hook for backward compatibility\nexport function useIsMobile(): boolean {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${BREAKPOINTS.mobile - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < BREAKPOINTS.mobile)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < BREAKPOINTS.mobile)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n\n// Enhanced mobile detection hook with comprehensive device information\nexport function useDeviceInfo(): DeviceInfo {\n const [deviceInfo, setDeviceInfo] = React.useState<DeviceInfo>(() => {\n if (typeof window === 'undefined') {\n return {\n isMobile: false,\n isTablet: false,\n isDesktop: true,\n isTouchDevice: false,\n platform: 'unknown',\n supportsHaptics: false,\n screenSize: { width: 1920, height: 1080 },\n orientation: 'landscape'\n }\n }\n \n const width = window.innerWidth\n const height = window.innerHeight\n \n return {\n isMobile: width < BREAKPOINTS.mobile,\n isTablet: width >= BREAKPOINTS.mobile && width < BREAKPOINTS.desktop,\n isDesktop: width >= BREAKPOINTS.desktop,\n isTouchDevice: isTouchDevice(),\n platform: detectPlatform(),\n supportsHaptics: supportsHaptics(),\n screenSize: { width, height },\n orientation: width > height ? 'landscape' : 'portrait'\n }\n })\n\n React.useEffect(() => {\n const updateDeviceInfo = () => {\n const width = window.innerWidth\n const height = window.innerHeight\n \n setDeviceInfo({\n isMobile: width < BREAKPOINTS.mobile,\n isTablet: width >= BREAKPOINTS.mobile && width < BREAKPOINTS.desktop,\n isDesktop: width >= BREAKPOINTS.desktop,\n isTouchDevice: isTouchDevice(),\n platform: detectPlatform(),\n supportsHaptics: supportsHaptics(),\n screenSize: { width, height },\n orientation: width > height ? 'landscape' : 'portrait'\n })\n }\n\n // Listen for resize events\n window.addEventListener('resize', updateDeviceInfo)\n \n // Listen for orientation changes\n window.addEventListener('orientationchange', updateDeviceInfo)\n \n // Listen for media query changes for better performance\n const mobileQuery = window.matchMedia(`(max-width: ${BREAKPOINTS.mobile - 1}px)`)\n const tabletQuery = window.matchMedia(`(min-width: ${BREAKPOINTS.mobile}px) and (max-width: ${BREAKPOINTS.desktop - 1}px)`)\n const desktopQuery = window.matchMedia(`(min-width: ${BREAKPOINTS.desktop}px)`)\n \n mobileQuery.addEventListener('change', updateDeviceInfo)\n tabletQuery.addEventListener('change', updateDeviceInfo)\n desktopQuery.addEventListener('change', updateDeviceInfo)\n \n return () => {\n window.removeEventListener('resize', updateDeviceInfo)\n window.removeEventListener('orientationchange', updateDeviceInfo)\n mobileQuery.removeEventListener('change', updateDeviceInfo)\n tabletQuery.removeEventListener('change', updateDeviceInfo)\n desktopQuery.removeEventListener('change', updateDeviceInfo)\n }\n }, [])\n\n return deviceInfo\n}\n\n// Hook for container queries support (Tailwind CSS v4)\nexport function useContainerQuery(containerRef: React.RefObject<HTMLElement>, query: string) {\n const [matches, setMatches] = React.useState(false)\n\n React.useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const size = entry.contentBoxSize[0]\n const width = size?.inlineSize || 0\n const height = size?.blockSize || 0\n \n // Simple container query evaluation\n // This is a basic implementation - in production you might want to use a library\n const queryMatch = evaluateContainerQuery(query, { width, height })\n setMatches(queryMatch)\n }\n })\n\n observer.observe(container)\n\n return () => {\n observer.disconnect()\n }\n }, [query])\n\n return matches\n}\n\n// Simple container query evaluator\nfunction evaluateContainerQuery(query: string, dimensions: { width: number; height: number }): boolean {\n // Basic implementation - supports (min-width: Xpx) and (max-width: Xpx)\n const minWidthMatch = query.match(/\\(min-width:\\s*(\\d+)px\\)/)\n const maxWidthMatch = query.match(/\\(max-width:\\s*(\\d+)px\\)/)\n \n if (minWidthMatch && minWidthMatch[1]) {\n const minWidth = parseInt(minWidthMatch[1], 10)\n return dimensions.width >= minWidth\n }\n \n if (maxWidthMatch && maxWidthMatch[1]) {\n const maxWidth = parseInt(maxWidthMatch[1], 10)\n return dimensions.width <= maxWidth\n }\n \n return false\n}\n\n// Performance optimization hook for mobile devices\nexport function useMobileOptimizations() {\n const { platform, isMobile } = useDeviceInfo()\n \n React.useEffect(() => {\n if (!isMobile) return\n \n // iOS-specific optimizations\n if (platform === 'ios') {\n // Prevent zoom on double tap for iOS Safari\n const preventZoom = (e: TouchEvent) => {\n if (e.touches.length > 1) {\n e.preventDefault()\n }\n }\n \n document.addEventListener('touchstart', preventZoom, { passive: false })\n \n // Enable momentum scrolling\n ;(document.body.style as any).webkitOverflowScrolling = 'touch'\n \n return () => {\n document.removeEventListener('touchstart', preventZoom)\n }\n }\n \n // Android-specific optimizations\n if (platform === 'android') {\n // Improve touch responsiveness\n document.body.style.touchAction = 'manipulation'\n }\n \n // General mobile optimizations\n // Improve rendering performance\n document.documentElement.style.setProperty('--webkit-transform', 'translateZ(0)')\n document.documentElement.style.setProperty('--transform', 'translateZ(0)')\n \n }, [platform, isMobile])\n}\n\n// Haptic feedback utility\nexport function useHapticFeedback() {\n const { supportsHaptics } = useDeviceInfo()\n \n const triggerHaptic = React.useCallback((type: 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' = 'light') => {\n if (!supportsHaptics) return\n \n // Map haptic types to vibration patterns\n const patterns = {\n light: [10],\n medium: [20],\n heavy: [30],\n success: [10, 10, 10],\n warning: [20, 20],\n error: [50, 20, 50]\n }\n \n const pattern = patterns[type]\n \n if ('vibrate' in navigator) {\n navigator.vibrate(pattern)\n }\n }, [supportsHaptics])\n \n return { triggerHaptic, supportsHaptics }\n}\n","\"use client\"\n\nimport { useDeviceInfo, useHapticFeedback } from \"@rp/ui/hooks/use-mobile\"\nimport * as React from \"react\"\n\n// Gesture types\nexport type GestureType =\n\t| \"tap\"\n\t| \"double-tap\"\n\t| \"long-press\"\n\t| \"swipe-left\"\n\t| \"swipe-right\"\n\t| \"swipe-up\"\n\t| \"swipe-down\"\n\t| \"pinch-in\"\n\t| \"pinch-out\"\n\n// Gesture event data\nexport interface GestureEvent {\n\ttype: GestureType\n\tstartPoint: { x: number; y: number }\n\tcurrentPoint: { x: number; y: number }\n\tvelocity?: { x: number; y: number }\n\tscale?: number\n\trotation?: number\n\tdistance?: number\n\tduration: number\n\tpreventDefault: () => void\n\ttarget: HTMLElement\n}\n\n// Gesture configuration\nexport interface GestureConfig {\n\tenabledGestures?: GestureType[]\n\ttapThreshold?: number // ms\n\tdoubleTapThreshold?: number // ms\n\tlongPressThreshold?: number // ms\n\tswipeThreshold?: number // px\n\tswipeVelocityThreshold?: number // px/ms\n\tpinchThreshold?: number // scale difference\n\trotationThreshold?: number // degrees\n\tenableHapticFeedback?: boolean\n}\n\n// Default configuration\nconst defaultConfig: Required<GestureConfig> = {\n\tenabledGestures: [\n\t\t\"tap\",\n\t\t\"double-tap\",\n\t\t\"long-press\",\n\t\t\"swipe-left\",\n\t\t\"swipe-right\",\n\t\t\"swipe-up\",\n\t\t\"swipe-down\",\n\t\t\"pinch-in\",\n\t\t\"pinch-out\"\n\t],\n\ttapThreshold: 200,\n\tdoubleTapThreshold: 300,\n\tlongPressThreshold: 500,\n\tswipeThreshold: 50,\n\tswipeVelocityThreshold: 0.5,\n\tpinchThreshold: 0.1,\n\trotationThreshold: 15,\n\tenableHapticFeedback: true\n}\n\n// Touch point interface\ninterface TouchPoint {\n\tid: number\n\tx: number\n\ty: number\n\ttimestamp: number\n}\n\n// Gesture state\ninterface GestureState {\n\tisTracking: boolean\n\ttouches: TouchPoint[]\n\tstartTouches: TouchPoint[]\n\tlastTap?: { timestamp: number; point: { x: number; y: number } }\n\tlongPressTimer?: NodeJS.Timeout\n\tinitialDistance?: number\n\tinitialScale?: number\n\tlastScale?: number\n}\n\n// Touch gesture hook\nexport function useTouchGestures(\n\tref: React.RefObject<HTMLElement>,\n\tonGesture: (event: GestureEvent) => void,\n\tconfig: GestureConfig = {}\n) {\n\tconst mergedConfig = { ...defaultConfig, ...config }\n\tconst { isTouchDevice } = useDeviceInfo()\n\tconst { triggerHaptic } = useHapticFeedback()\n\tconst gestureState = React.useRef<GestureState>({\n\t\tisTracking: false,\n\t\ttouches: [],\n\t\tstartTouches: []\n\t})\n\n\t// Helper functions\n\tconst getTouchPoint = (touch: Touch): TouchPoint => ({\n\t\tid: touch.identifier,\n\t\tx: touch.clientX,\n\t\ty: touch.clientY,\n\t\ttimestamp: Date.now()\n\t})\n\n\tconst getDistance = (p1: TouchPoint, p2: TouchPoint): number =>\n\t\tMath.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2))\n\n\tconst getVelocity = (start: TouchPoint, end: TouchPoint): { x: number; y: number } => {\n\t\tconst timeDiff = Math.max(end.timestamp - start.timestamp, 1)\n\t\treturn {\n\t\t\tx: (end.x - start.x) / timeDiff,\n\t\t\ty: (end.y - start.y) / timeDiff\n\t\t}\n\t}\n\n\tconst createGestureEvent = (\n\t\ttype: GestureType,\n\t\tstartPoint: TouchPoint,\n\t\tcurrentPoint: TouchPoint,\n\t\tadditionalData: Partial<GestureEvent> = {}\n\t): GestureEvent => ({\n\t\ttype,\n\t\tstartPoint: { x: startPoint.x, y: startPoint.y },\n\t\tcurrentPoint: { x: currentPoint.x, y: currentPoint.y },\n\t\tduration: currentPoint.timestamp - startPoint.timestamp,\n\t\ttarget: ref.current!,\n\t\tpreventDefault: () => {},\n\t\t...additionalData\n\t})\n\n\t// Handle touch start\n\tconst handleTouchStart = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tif (!mergedConfig.enabledGestures.length) return\n\n\t\t\tconst touches = Array.from(e.touches).map(getTouchPoint)\n\t\t\tconst state = gestureState.current\n\n\t\t\tstate.isTracking = true\n\t\t\tstate.touches = touches\n\t\t\tstate.startTouches = [...touches]\n\n\t\t\t// Clear any existing long press timer\n\t\t\tif (state.longPressTimer) {\n\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t}\n\n\t\t\t// Set up long press detection for single touch\n\t\t\tif (touches.length === 1 && mergedConfig.enabledGestures.includes(\"long-press\")) {\n\t\t\t\tstate.longPressTimer = setTimeout(() => {\n\t\t\t\t\tif (state.touches.length === 1 && touches[0]) {\n\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"long-press\", touches[0], touches[0])\n\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\ttriggerHaptic(\"heavy\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, mergedConfig.longPressThreshold)\n\t\t\t}\n\n\t\t\t// Handle multi-touch gestures\n\t\t\tif (touches.length === 2 && touches[0] && touches[1]) {\n\t\t\t\tstate.initialDistance = getDistance(touches[0], touches[1])\n\t\t\t\tstate.initialScale = 1\n\t\t\t\tstate.lastScale = 1\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture, triggerHaptic]\n\t)\n\n\t// Handle touch move\n\tconst handleTouchMove = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tconst state = gestureState.current\n\t\t\tif (!state.isTracking) return\n\n\t\t\tconst touches = Array.from(e.touches).map(getTouchPoint)\n\t\t\tstate.touches = touches\n\n\t\t\t// Handle pinch gesture\n\t\t\tif (touches.length === 2 && state.initialDistance && touches[0] && touches[1]) {\n\t\t\t\tconst currentDistance = getDistance(touches[0], touches[1])\n\t\t\t\tconst scale = currentDistance / state.initialDistance\n\t\t\t\tconst scaleDiff = Math.abs(scale - (state.lastScale || 1))\n\n\t\t\t\tif (scaleDiff > mergedConfig.pinchThreshold) {\n\t\t\t\t\tconst gestureType = scale > (state.lastScale || 1) ? \"pinch-out\" : \"pinch-in\"\n\n\t\t\t\t\tif (mergedConfig.enabledGestures.includes(gestureType)) {\n\t\t\t\t\t\tconst centerPoint = {\n\t\t\t\t\t\t\tx: (touches[0].x + touches[1].x) / 2,\n\t\t\t\t\t\t\ty: (touches[0].y + touches[1].y) / 2,\n\t\t\t\t\t\t\tid: -1,\n\t\t\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst startCenterPoint = {\n\t\t\t\t\t\t\tx: ((state.startTouches[0]?.x ?? 0) + (state.startTouches[1]?.x ?? 0)) / 2,\n\t\t\t\t\t\t\ty: ((state.startTouches[0]?.y ?? 0) + (state.startTouches[1]?.y ?? 0)) / 2,\n\t\t\t\t\t\t\tid: -1,\n\t\t\t\t\t\t\ttimestamp: state.startTouches[0]?.timestamp ?? Date.now()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst gestureEvent = createGestureEvent(gestureType, startCenterPoint, centerPoint, {\n\t\t\t\t\t\t\tscale,\n\t\t\t\t\t\t\tdistance: currentDistance\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tonGesture(gestureEvent)\n\t\t\t\t\t\tstate.lastScale = scale\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear long press timer on move\n\t\t\tif (state.longPressTimer && touches.length === 1 && state.startTouches[0] && touches[0]) {\n\t\t\t\tconst startTouch = state.startTouches[0]\n\t\t\t\tconst currentTouch = touches[0]\n\t\t\t\tconst distance = getDistance(startTouch, currentTouch)\n\n\t\t\t\tif (distance > mergedConfig.swipeThreshold) {\n\t\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t\t\tstate.longPressTimer = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture]\n\t)\n\n\t// Handle touch end\n\tconst handleTouchEnd = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tconst state = gestureState.current\n\t\t\tif (!state.isTracking) return\n\n\t\t\tconst endTouches = Array.from(e.changedTouches).map(getTouchPoint)\n\t\t\tconst currentTime = Date.now()\n\n\t\t\t// Clear long press timer\n\t\t\tif (state.longPressTimer) {\n\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t\tstate.longPressTimer = undefined\n\t\t\t}\n\n\t\t\t// Handle single touch gestures\n\t\t\tif (\n\t\t\t\tstate.startTouches.length === 1 &&\n\t\t\t\tendTouches.length === 1 &&\n\t\t\t\tstate.startTouches[0] &&\n\t\t\t\tendTouches[0]\n\t\t\t) {\n\t\t\t\tconst startTouch = state.startTouches[0]\n\t\t\t\tconst endTouch = endTouches[0]\n\t\t\t\tconst distance = getDistance(startTouch, endTouch)\n\t\t\t\tconst duration = endTouch.timestamp - startTouch.timestamp\n\n\t\t\t\t// Check for swipe gestures\n\t\t\t\tif (distance > mergedConfig.swipeThreshold) {\n\t\t\t\t\tconst velocity = getVelocity(startTouch, endTouch)\n\t\t\t\t\tconst absVelX = Math.abs(velocity.x)\n\t\t\t\t\tconst absVelY = Math.abs(velocity.y)\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tabsVelX > mergedConfig.swipeVelocityThreshold ||\n\t\t\t\t\t\tabsVelY > mergedConfig.swipeVelocityThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\tlet gestureType: GestureType\n\n\t\t\t\t\t\tif (absVelX > absVelY) {\n\t\t\t\t\t\t\tgestureType = velocity.x > 0 ? \"swipe-right\" : \"swipe-left\"\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tgestureType = velocity.y > 0 ? \"swipe-down\" : \"swipe-up\"\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(gestureType)) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(gestureType, startTouch, endTouch, {\n\t\t\t\t\t\t\t\tvelocity,\n\t\t\t\t\t\t\t\tdistance\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"light\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Check for tap gestures\n\t\t\t\telse if (duration < mergedConfig.tapThreshold && distance < mergedConfig.swipeThreshold) {\n\t\t\t\t\t// Check for double tap\n\t\t\t\t\tif (\n\t\t\t\t\t\tstate.lastTap &&\n\t\t\t\t\t\tcurrentTime - state.lastTap.timestamp < mergedConfig.doubleTapThreshold &&\n\t\t\t\t\t\tgetDistance(\n\t\t\t\t\t\t\t{ ...state.lastTap.point, id: -1, timestamp: state.lastTap.timestamp },\n\t\t\t\t\t\t\tendTouch\n\t\t\t\t\t\t) < mergedConfig.swipeThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(\"double-tap\")) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"double-tap\", startTouch, endTouch)\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"medium\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.lastTap = undefined\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Single tap\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(\"tap\")) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"tap\", startTouch, endTouch)\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"light\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.lastTap = {\n\t\t\t\t\t\t\ttimestamp: currentTime,\n\t\t\t\t\t\t\tpoint: { x: endTouch.x, y: endTouch.y }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Reset gesture state\n\t\t\tif (e.touches.length === 0) {\n\t\t\t\tstate.isTracking = false\n\t\t\t\tstate.touches = []\n\t\t\t\tstate.startTouches = []\n\t\t\t\tstate.initialDistance = undefined\n\t\t\t\tstate.initialScale = undefined\n\t\t\t\tstate.lastScale = undefined\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture, triggerHaptic]\n\t)\n\n\t// Attach event listeners\n\tReact.useEffect(() => {\n\t\tconst element = ref.current\n\t\tif (!element || !isTouchDevice) return\n\n\t\telement.addEventListener(\"touchstart\", handleTouchStart, { passive: false })\n\t\telement.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n\t\telement.addEventListener(\"touchend\", handleTouchEnd, { passive: false })\n\t\telement.addEventListener(\"touchcancel\", handleTouchEnd, { passive: false })\n\n\t\treturn () => {\n\t\t\telement.removeEventListener(\"touchstart\", handleTouchStart)\n\t\t\telement.removeEventListener(\"touchmove\", handleTouchMove)\n\t\t\telement.removeEventListener(\"touchend\", handleTouchEnd)\n\t\t\telement.removeEventListener(\"touchcancel\", handleTouchEnd)\n\t\t}\n\t}, [handleTouchStart, handleTouchMove, handleTouchEnd, isTouchDevice])\n\n\treturn {\n\t\tisGestureEnabled: isTouchDevice && mergedConfig.enabledGestures.length > 0\n\t}\n}\n\n// Media player specific gesture hook with predefined actions\nexport function useMediaGestures(\n\tref: React.RefObject<HTMLElement>,\n\tactions: {\n\t\tonPlayPause?: () => void\n\t\tonSeek?: (direction: \"forward\" | \"backward\", amount: number) => void\n\t\tonVolumeChange?: (direction: \"up\" | \"down\", amount: number) => void\n\t\tonToggleFullscreen?: () => void\n\t\tonZoom?: (scale: number) => void\n\t}\n) {\n\tconst handleGesture = React.useCallback(\n\t\t(event: GestureEvent) => {\n\t\t\tconst { type, velocity, distance, scale } = event\n\n\t\t\tswitch (type) {\n\t\t\t\tcase \"double-tap\":\n\t\t\t\t\t// Double tap to play/pause\n\t\t\t\t\tactions.onPlayPause?.()\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-left\":\n\t\t\t\t\t// Swipe left to seek backward\n\t\t\t\t\tconst backwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n\t\t\t\t\tactions.onSeek?.(\"backward\", backwardAmount)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-right\":\n\t\t\t\t\t// Swipe right to seek forward\n\t\t\t\t\tconst forwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n\t\t\t\t\tactions.onSeek?.(\"forward\", forwardAmount)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-up\":\n\t\t\t\t\t// Swipe up on right side for volume up\n\t\t\t\t\tif (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n\t\t\t\t\t\tconst volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n\t\t\t\t\t\tactions.onVolumeChange?.(\"up\", volumeAmount)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-down\":\n\t\t\t\t\t// Swipe down on right side for volume down\n\t\t\t\t\tif (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n\t\t\t\t\t\tconst volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n\t\t\t\t\t\tactions.onVolumeChange?.(\"down\", volumeAmount)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"pinch-out\":\n\t\t\t\t\t// Pinch out to zoom in (for video zoom functionality)\n\t\t\t\t\tactions.onZoom?.(scale || 1)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"pinch-in\":\n\t\t\t\t\t// Pinch in to zoom out\n\t\t\t\t\tactions.onZoom?.(scale || 1)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"long-press\":\n\t\t\t\t\t// Long press for fullscreen toggle\n\t\t\t\t\tactions.onToggleFullscreen?.()\n\t\t\t\t\tbreak\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t},\n\t\t[actions, ref]\n\t)\n\n\tconst gestureConfig: GestureConfig = {\n\t\tenabledGestures: [\n\t\t\t\"tap\",\n\t\t\t\"double-tap\",\n\t\t\t\"long-press\",\n\t\t\t\"swipe-left\",\n\t\t\t\"swipe-right\",\n\t\t\t\"swipe-up\",\n\t\t\t\"swipe-down\",\n\t\t\t\"pinch-in\",\n\t\t\t\"pinch-out\"\n\t\t],\n\t\tenableHapticFeedback: true,\n\t\tswipeThreshold: 30,\n\t\tswipeVelocityThreshold: 0.3\n\t}\n\n\treturn useTouchGestures(ref, handleGesture, gestureConfig)\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\"\n\ninterface SubtitleCue {\n\tstart: number\n\tend: number\n\ttext: string\n}\n\nexport interface SubtitleTrack {\n\tid: string\n\tlabel: string\n\tlanguage?: string\n\tsrc?: string\n}\n\nexport interface UseEnhancedSubtitlesOptions {\n\tsubtitleSrc?: string\n\tsubtitleTracks?: SubtitleTrack[]\n\tdefaultFontSize?: \"small\" | \"medium\" | \"large\"\n\tonLoadError?: (error: Error) => void\n}\n\nexport function useEnhancedSubtitles({\n\tsubtitleSrc,\n\tsubtitleTracks = [],\n\tdefaultFontSize = \"medium\",\n\tonLoadError\n}: UseEnhancedSubtitlesOptions = {}) {\n\tconst [subtitlesEnabled, setSubtitlesEnabled] = useState(false)\n\tconst [subtitleCues, setSubtitleCues] = useState<SubtitleCue[]>([])\n\tconst [currentSubtitle, setCurrentSubtitle] = useState(\"\")\n\tconst [currentTrackId, setCurrentTrackId] = useState<string | null>(null)\n\tconst [fontSize, setFontSize] = useState<\"small\" | \"medium\" | \"large\">(defaultFontSize)\n\tconst [loadError, setLoadError] = useState<Error | null>(null)\n\tconst [isLoading, setIsLoading] = useState(false)\n\n\t// Size mapping for subtitle font sizes\n\tconst sizeMap = {\n\t\tsmall: \"text-sm\",\n\t\tmedium: \"text-base\",\n\t\tlarge: \"text-lg\"\n\t}\n\n\t// Determine if subtitles are available\n\tconst hasSubtitles = !!(subtitleSrc || (subtitleTracks && subtitleTracks.length > 0))\n\n\t// Parse VTT/WebVTT timestamp\n\tconst parseVTTTime = (timeStr: string): number => {\n\t\tconst parts = timeStr.split(\":\")\n\t\tconst seconds = parts[2] ? parseFloat(parts[2]) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds\n\t}\n\n\t// Parse SRT timestamp\n\tconst parseSRTTime = (timeStr: string): number => {\n\t\t// SRT format: 00:00:00,000 (hours:minutes:seconds,milliseconds)\n\t\tconst [time, ms] = timeStr.split(\",\")\n\t\tconst parts = (time || \"\").split(\":\")\n\t\tconst milliseconds = ms ? parseInt(ms, 10) / 1000 : 0\n\t\tconst seconds = parts[2] ? parseInt(parts[2], 10) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds + milliseconds\n\t}\n\n\t// Load and parse subtitle file\n\tconst loadSubtitles = async (url: string) => {\n\t\tsetIsLoading(true)\n\t\tsetLoadError(null)\n\n\t\ttry {\n\t\t\tconst response = await fetch(url)\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to load subtitles: ${response.status} ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst text = await response.text()\n\t\t\tconst cues: SubtitleCue[] = []\n\t\t\tconst lines = text.split(\"\\n\")\n\t\t\tlet i = 0\n\n\t\t\t// Detect format (VTT or SRT)\n\t\t\tconst isVTT = text.includes(\"WEBVTT\") || url.endsWith(\".vtt\")\n\t\t\tconst isSRT = url.endsWith(\".srt\") || /^\\d+$/.test(lines[0]?.trim() || \"\")\n\n\t\t\tif (isVTT) {\n\t\t\t\t// Parse VTT format\n\t\t\t\twhile (i < lines.length) {\n\t\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\t\tconst start = parseVTTTime(startStr || \"\")\n\t\t\t\t\t\tconst end = parseVTTTime(endStr || \"\")\n\n\t\t\t\t\t\ti++\n\t\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t} else if (isSRT) {\n\t\t\t\t// Parse SRT format\n\t\t\t\twhile (i < lines.length) {\n\t\t\t\t\t// Skip the sequence number\n\t\t\t\t\tif (/^\\d+$/.test(lines[i]?.trim() || \"\")) {\n\t\t\t\t\t\ti++\n\t\t\t\t\t\t// Parse timestamp line\n\t\t\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\t\t\tconst start = parseSRTTime(startStr || \"\")\n\t\t\t\t\t\t\tconst end = parseSRTTime(endStr || \"\")\n\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Unsupported subtitle format. Only VTT and SRT are supported.\")\n\t\t\t}\n\n\t\t\tif (cues.length === 0) {\n\t\t\t\tthrow new Error(\"No subtitle cues found in file\")\n\t\t\t}\n\n\t\t\tsetSubtitleCues(cues)\n\t\t\tsetIsLoading(false)\n\t\t} catch (error) {\n\t\t\tconst err = error instanceof Error ? error : new Error(\"Failed to load subtitles\")\n\t\t\tconsole.error(\"Failed to load subtitles:\", err)\n\t\t\tsetLoadError(err)\n\t\t\tsetIsLoading(false)\n\t\t\tsetSubtitleCues([])\n\t\t\tonLoadError?.(err)\n\t\t}\n\t}\n\n\t// Get current subtitle text based on time\n\tconst getCurrentSubtitle = (currentTime: number) => {\n\t\tif (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n\n\t\tconst currentCue = subtitleCues.find(\n\t\t\t(cue) => currentTime >= cue.start && currentTime <= cue.end\n\t\t)\n\t\treturn currentCue?.text || \"\"\n\t}\n\n\t// Toggle subtitles on/off\n\tconst toggleSubtitles = () => {\n\t\tsetSubtitlesEnabled((prev) => {\n\t\t\tconst newEnabled = !prev\n\n\t\t\tif (newEnabled && !loadError) {\n\t\t\t\t// Try to load subtitles if not already loaded\n\t\t\t\tif (subtitleCues.length === 0 && !isLoading) {\n\t\t\t\t\t// Load default subtitle source or first track\n\t\t\t\t\tconst srcToLoad = subtitleSrc || subtitleTracks[0]?.src\n\t\t\t\t\tif (srcToLoad) {\n\t\t\t\t\t\tloadSubtitles(srcToLoad)\n\t\t\t\t\t\tif (subtitleTracks[0]) {\n\t\t\t\t\t\t\tsetCurrentTrackId(subtitleTracks[0].id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!newEnabled) {\n\t\t\t\tsetCurrentSubtitle(\"\")\n\t\t\t}\n\n\t\t\treturn newEnabled\n\t\t})\n\t}\n\n\t// Select a specific subtitle track\n\tconst selectSubtitleTrack = (trackId: string | null) => {\n\t\tif (!trackId) {\n\t\t\t// Turn off subtitles\n\t\t\tsetSubtitlesEnabled(false)\n\t\t\tsetCurrentTrackId(null)\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t\treturn\n\t\t}\n\n\t\tconst track = subtitleTracks.find((t) => t.id === trackId)\n\t\tif (track?.src) {\n\t\t\tsetCurrentTrackId(trackId)\n\t\t\tloadSubtitles(track.src)\n\t\t\tsetSubtitlesEnabled(true)\n\t\t}\n\t}\n\n\t// Change subtitle font size\n\tconst changeSubtitleFontSize = (size: \"small\" | \"medium\" | \"large\") => {\n\t\tsetFontSize(size)\n\t}\n\n\t// Get CSS classes for subtitle display\n\tconst getSubtitleStyles = {\n\t\tfontSize: sizeMap[fontSize],\n\t\tclassName: `${sizeMap[fontSize]} font-medium`\n\t}\n\n\t// Clear subtitle on disable\n\tuseEffect(() => {\n\t\tif (!subtitlesEnabled) {\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t}\n\t}, [subtitlesEnabled])\n\n\t// Auto-load default subtitles on mount if available\n\tuseEffect(() => {\n\t\tif (subtitleSrc && !subtitleCues.length && !loadError && !isLoading) {\n\t\t\t// Don't auto-load, wait for user to enable\n\t\t\t// This prevents errors on initial load\n\t\t}\n\t}, [])\n\n\treturn {\n\t\t// State\n\t\tsubtitlesEnabled,\n\t\tcurrentSubtitle,\n\t\tsubtitleCues,\n\t\tcurrentTrackId,\n\t\tfontSize,\n\t\tloadError,\n\t\tisLoading,\n\t\thasSubtitles,\n\n\t\t// Actions\n\t\ttoggleSubtitles,\n\t\tselectSubtitleTrack,\n\t\tchangeSubtitleFontSize,\n\t\tsetCurrentSubtitle,\n\n\t\t// Utilities\n\t\tgetCurrentSubtitle,\n\t\tgetSubtitleStyles,\n\n\t\t// Track info\n\t\tavailableTracks: subtitleTracks\n\t}\n}\n","import { useCallback, useEffect } from \"react\"\nimport type { VideoControls } from \"./useVideoPlayer\"\n\ninterface UseKeyboardShortcutsProps {\n\tvideoControls: VideoControls\n\ttoggleSubtitles: () => void\n\ttakeScreenshot: (ctrlKey?: boolean) => void\n\tduration: number\n}\n\nexport function useKeyboardShortcuts({\n\tvideoControls,\n\ttoggleSubtitles,\n\ttakeScreenshot,\n\tduration\n}: UseKeyboardShortcutsProps) {\n\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\tconst video = document.querySelector(\"video\")\n\t\tif (!video) return\n\n\t\tswitch (e.key.toLowerCase()) {\n\t\t\tcase \" \":\n\t\t\tcase \"k\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.togglePlay()\n\t\t\t\tbreak\n\t\t\tcase \"j\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.seekBackward()\n\t\t\t\tbreak\n\t\t\tcase \"l\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.seekForward()\n\t\t\t\tbreak\n\t\t\tcase \"arrowleft\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.currentTime = Math.max(0, video.currentTime - 5)\n\t\t\t\tbreak\n\t\t\tcase \"arrowright\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.currentTime = Math.min(duration, video.currentTime + 5)\n\t\t\t\tbreak\n\t\t\tcase \"arrowup\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.volume = Math.min(1, video.volume + 0.1)\n\t\t\t\tbreak\n\t\t\tcase \"arrowdown\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.volume = Math.max(0, video.volume - 0.1)\n\t\t\t\tbreak\n\t\t\tcase \"m\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.toggleMute()\n\t\t\t\tbreak\n\t\t\tcase \"f\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.toggleFullscreen()\n\t\t\t\tbreak\n\t\t\tcase \"c\":\n\t\t\t\te.preventDefault()\n\t\t\t\ttoggleSubtitles()\n\t\t\t\tbreak\n\t\t\tcase \"s\":\n\t\t\t\te.preventDefault()\n\t\t\t\ttakeScreenshot(e.ctrlKey || e.metaKey)\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown)\n\t\treturn () => document.removeEventListener(\"keydown\", handleKeyDown)\n\t}, [handleKeyDown])\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport function useMediaControls(isPlaying: boolean, showSettings: boolean) {\n\tconst [controlsVisible, setControlsVisible] = useState(true)\n\tconst [showVolumeSlider, setShowVolumeSlider] = useState(false)\n\tconst hideTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n\n\tconst showControls = () => {\n\t\tsetControlsVisible(true)\n\t\tif (hideTimeoutRef.current) {\n\t\t\tclearTimeout(hideTimeoutRef.current)\n\t\t}\n\n\t\tif (isPlaying && !showSettings) {\n\t\t\thideTimeoutRef.current = setTimeout(() => {\n\t\t\t\tsetControlsVisible(false)\n\t\t\t}, 3000)\n\t\t}\n\t}\n\n\tconst handleMouseMove = () => {\n\t\tshowControls()\n\t}\n\n\tconst handleMouseEnter = () => {\n\t\tsetControlsVisible(true)\n\t}\n\n\tconst handleMouseLeave = () => {\n\t\tif (isPlaying) {\n\t\t\tsetControlsVisible(false)\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tshowControls()\n\t\treturn () => {\n\t\t\tif (hideTimeoutRef.current) {\n\t\t\t\tclearTimeout(hideTimeoutRef.current)\n\t\t\t}\n\t\t}\n\t}, [showControls])\n\n\treturn {\n\t\tcontrolsVisible,\n\t\tshowVolumeSlider,\n\t\tsetShowVolumeSlider,\n\t\thandleMouseMove,\n\t\thandleMouseEnter,\n\t\thandleMouseLeave\n\t}\n}\n","import { useCallback } from \"react\"\n\nexport function useScreenshot(videoRef: React.RefObject<HTMLVideoElement | null>) {\n\tconst takeScreenshot = (ctrlKey: boolean = false) => {\n\t\tif (!videoRef.current) return\n\n\t\tconst video = videoRef.current\n\t\tconst canvas = document.createElement(\"canvas\")\n\t\tcanvas.width = video.videoWidth\n\t\tcanvas.height = video.videoHeight\n\t\tconst ctx = canvas.getContext(\"2d\")\n\t\tif (!ctx) return\n\n\t\ttry {\n\t\t\t// Draw the video frame to canvas\n\t\t\tctx.drawImage(video, 0, 0)\n\n\t\t\t// Try to export the canvas\n\t\t\tcanvas.toBlob((blob) => {\n\t\t\t\tif (!blob) {\n\t\t\t\t\tconsole.error(\"Failed to create blob from canvas\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (ctrlKey) {\n\t\t\t\t\t// Copy to clipboard\n\t\t\t\t\tif (navigator.clipboard && window.ClipboardItem) {\n\t\t\t\t\t\tconst item = new ClipboardItem({ \"image/png\": blob })\n\t\t\t\t\t\tnavigator.clipboard.write([item]).catch((err) => {\n\t\t\t\t\t\t\tconsole.error(\"Failed to copy to clipboard:\", err)\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(\"Clipboard API not supported\")\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Download\n\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\tconst a = document.createElement(\"a\")\n\t\t\t\t\ta.href = url\n\t\t\t\t\ta.download = `screenshot-${Date.now()}.png`\n\t\t\t\t\ta.click()\n\t\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t}\n\t\t\t}, \"image/png\")\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.includes(\"tainted\")) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"Canvas is tainted - video source may not have proper CORS headers. Try setting crossOrigin='anonymous' on the video element.\"\n\t\t\t\t)\n\t\t\t\talert(\n\t\t\t\t\t\"Screenshot failed: The video source doesn't allow screenshots due to CORS policy. Please ensure the video server includes proper CORS headers or set crossOrigin='anonymous' on the video player.\"\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tconsole.error(\"Screenshot failed:\", error)\n\t\t\t\talert(\"Screenshot failed: \" + (error instanceof Error ? error.message : \"Unknown error\"))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { takeScreenshot }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport interface BufferedRange {\n\tstart: number\n\tend: number\n\tpercentage: number\n}\n\nexport interface VideoState {\n\tisPlaying: boolean\n\tcurrentTime: number\n\tduration: number\n\tvolume: number\n\tisMuted: boolean\n\tisFullscreen: boolean\n\tisLoading: boolean\n\tisSeeking: boolean\n\tisBuffering: boolean\n\tbufferedRanges: BufferedRange[]\n}\n\nexport interface VideoControls {\n\ttogglePlay: () => void\n\tseekForward: (seconds?: number) => void\n\tseekBackward: (seconds?: number) => void\n\ttoggleMute: () => void\n\tsetVolume: (volume: number) => void\n\ttoggleFullscreen: () => void\n\tseekTo: (time: number) => void\n}\n\nexport function useVideoPlayer(containerRef: React.RefObject<HTMLDivElement | null>) {\n\tconst videoRef = useRef<HTMLVideoElement>(null)\n\tconst [state, setState] = useState<VideoState>({\n\t\tisPlaying: false,\n\t\tcurrentTime: 0,\n\t\tduration: 0,\n\t\tvolume: 1,\n\t\tisMuted: false,\n\t\tisFullscreen: false,\n\t\tisLoading: true,\n\t\tisSeeking: false,\n\t\tisBuffering: false,\n\t\tbufferedRanges: []\n\t})\n\n\tuseEffect(() => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\n\t\tconst handleTimeUpdate = () => {\n\t\t\tsetState((prev) => ({ ...prev, currentTime: video.currentTime }))\n\t\t}\n\n\t\tconst handleLoadedMetadata = () => {\n\t\t\tsetState((prev) => ({ ...prev, duration: video.duration }))\n\t\t}\n\n\t\tconst handlePlay = () => {\n\t\t\tsetState((prev) => ({ ...prev, isPlaying: true, isBuffering: false }))\n\t\t}\n\n\t\tconst handlePause = () => {\n\t\t\tsetState((prev) => ({ ...prev, isPlaying: false }))\n\t\t}\n\n\t\tconst handleVolumeChange = () => {\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tvolume: video.volume,\n\t\t\t\tisMuted: video.muted\n\t\t\t}))\n\t\t}\n\n\t\t// Loading state handlers\n\t\tconst handleLoadStart = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: true }))\n\t\t}\n\n\t\tconst handleLoadedData = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: false }))\n\t\t}\n\n\t\t// Seeking state handlers\n\t\tconst handleSeeking = () => {\n\t\t\tsetState((prev) => ({ ...prev, isSeeking: true }))\n\t\t}\n\n\t\tconst handleSeeked = () => {\n\t\t\tsetState((prev) => ({ ...prev, isSeeking: false }))\n\t\t}\n\n\t\t// Buffering state handlers\n\t\tconst handleWaiting = () => {\n\t\t\tsetState((prev) => ({ ...prev, isBuffering: true }))\n\t\t}\n\n\t\tconst handlePlaying = () => {\n\t\t\tsetState((prev) => ({ ...prev, isBuffering: false, isLoading: false }))\n\t\t}\n\n\t\tconst handleCanPlay = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: false, isBuffering: false }))\n\t\t}\n\n\t\t// Progress handler for buffered ranges\n\t\tconst handleProgress = () => {\n\t\t\tif (!video.buffered || video.buffered.length === 0 || video.duration === 0) {\n\t\t\t\tsetState((prev) => ({ ...prev, bufferedRanges: [] }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst ranges: BufferedRange[] = []\n\t\t\tfor (let i = 0; i < video.buffered.length; i++) {\n\t\t\t\tconst start = video.buffered.start(i)\n\t\t\t\tconst end = video.buffered.end(i)\n\t\t\t\tranges.push({\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\tpercentage: ((end - start) / video.duration) * 100\n\t\t\t\t})\n\t\t\t}\n\t\t\tsetState((prev) => ({ ...prev, bufferedRanges: ranges }))\n\t\t}\n\n\t\tvideo.addEventListener(\"timeupdate\", handleTimeUpdate)\n\t\tvideo.addEventListener(\"loadedmetadata\", handleLoadedMetadata)\n\t\tvideo.addEventListener(\"play\", handlePlay)\n\t\tvideo.addEventListener(\"pause\", handlePause)\n\t\tvideo.addEventListener(\"volumechange\", handleVolumeChange)\n\t\tvideo.addEventListener(\"loadstart\", handleLoadStart)\n\t\tvideo.addEventListener(\"loadeddata\", handleLoadedData)\n\t\tvideo.addEventListener(\"seeking\", handleSeeking)\n\t\tvideo.addEventListener(\"seeked\", handleSeeked)\n\t\tvideo.addEventListener(\"waiting\", handleWaiting)\n\t\tvideo.addEventListener(\"playing\", handlePlaying)\n\t\tvideo.addEventListener(\"canplay\", handleCanPlay)\n\t\tvideo.addEventListener(\"progress\", handleProgress)\n\n\t\treturn () => {\n\t\t\tvideo.removeEventListener(\"timeupdate\", handleTimeUpdate)\n\t\t\tvideo.removeEventListener(\"loadedmetadata\", handleLoadedMetadata)\n\t\t\tvideo.removeEventListener(\"play\", handlePlay)\n\t\t\tvideo.removeEventListener(\"pause\", handlePause)\n\t\t\tvideo.removeEventListener(\"volumechange\", handleVolumeChange)\n\t\t\tvideo.removeEventListener(\"loadstart\", handleLoadStart)\n\t\t\tvideo.removeEventListener(\"loadeddata\", handleLoadedData)\n\t\t\tvideo.removeEventListener(\"seeking\", handleSeeking)\n\t\t\tvideo.removeEventListener(\"seeked\", handleSeeked)\n\t\t\tvideo.removeEventListener(\"waiting\", handleWaiting)\n\t\t\tvideo.removeEventListener(\"playing\", handlePlaying)\n\t\t\tvideo.removeEventListener(\"canplay\", handleCanPlay)\n\t\t\tvideo.removeEventListener(\"progress\", handleProgress)\n\t\t}\n\t}, [])\n\n\tconst togglePlay = () => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\n\t\tif (state.isPlaying) {\n\t\t\tvideo.pause()\n\t\t} else {\n\t\t\tvideo.play()\n\t\t}\n\t}\n\n\tconst seekForward = (seconds = 10) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.currentTime = Math.min(state.duration, video.currentTime + seconds)\n\t}\n\n\tconst seekBackward = (seconds = 10) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.currentTime = Math.max(0, video.currentTime - seconds)\n\t}\n\n\tconst toggleMute = () => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.muted = !state.isMuted\n\t}\n\n\tconst setVolume = (volume: number) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.volume = volume\n\t\tif (volume > 0 && state.isMuted) {\n\t\t\tvideo.muted = false\n\t\t}\n\t}\n\n\tconst toggleFullscreen = () => {\n\t\tconst container = containerRef.current\n\t\tif (!container) return\n\n\t\tif (!state.isFullscreen) {\n\t\t\tif (container.requestFullscreen) {\n\t\t\t\tcontainer.requestFullscreen()\n\t\t\t}\n\t\t} else {\n\t\t\tif (document.exitFullscreen) {\n\t\t\t\tdocument.exitFullscreen()\n\t\t\t}\n\t\t}\n\t\tsetState((prev) => ({ ...prev, isFullscreen: !prev.isFullscreen }))\n\t}\n\n\tconst seekTo = (time: number) => {\n\t\tconst video = videoRef.current\n\t\tif (!video || state.duration === 0) return\n\t\tvideo.currentTime = Math.max(0, Math.min(state.duration, time))\n\t}\n\n\tconst controls: VideoControls = {\n\t\ttogglePlay,\n\t\tseekForward,\n\t\tseekBackward,\n\t\ttoggleMute,\n\t\tsetVolume,\n\t\ttoggleFullscreen,\n\t\tseekTo\n\t}\n\n\treturn {\n\t\tvideoRef,\n\t\tstate,\n\t\tcontrols\n\t}\n}\n","/**\n * Intelligent Preloading Hook\n * Combines user behavior analysis with network conditions for optimal preloading\n */\n\nimport { useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { MediaSource } from \"../types\"\n\ninterface IntelligentPreloadingOptions {\n\t/** Enable user behavior tracking */\n\ttrackUserBehavior?: boolean\n\t/** Adapt to network conditions */\n\tadaptToNetwork?: boolean\n\t/** Preload strategy */\n\tstrategy?: \"conservative\" | \"balanced\" | \"aggressive\"\n\t/** Maximum number of items to preload */\n\tmaxPreloadItems?: number\n\t/** Preload radius for playlist items */\n\tpreloadRadius?: number\n}\n\ninterface UserBehaviorData {\n\tmouseMovements: number\n\tscrollEvents: number\n\tkeyPresses: number\n\tfocusEvents: number\n\ttimeOnPage: number\n\tengagementScore: number\n\tlastInteraction: number\n}\n\ninterface PreloadingDecision {\n\tshouldPreload: boolean\n\tpriority: \"high\" | \"medium\" | \"low\"\n\treason: string\n}\n\nexport const useIntelligentPreloading = (\n\tsources: MediaSource[],\n\toptions: IntelligentPreloadingOptions = {}\n) => {\n\tconst {\n\t\ttrackUserBehavior = true,\n\t\tadaptToNetwork = true,\n\t\tstrategy = \"balanced\",\n\t\tmaxPreloadItems = 3,\n\t\tpreloadRadius = 2\n\t} = options\n\n\tconst userBehaviorRef = useRef<UserBehaviorData>({\n\t\tmouseMovements: 0,\n\t\tscrollEvents: 0,\n\t\tkeyPresses: 0,\n\t\tfocusEvents: 0,\n\t\ttimeOnPage: 0,\n\t\tengagementScore: 0,\n\t\tlastInteraction: Date.now()\n\t})\n\n\tconst networkInfoRef = useRef<NetworkInformation | null>(null)\n\tconst preloadedItemsRef = useRef<Set<string>>(new Set())\n\tconst preloadQueueRef = useRef<Array<{ source: MediaSource; priority: number }>>([])\n\n\t// Calculate user engagement score\n\tconst calculateEngagementScore = useCallback((): number => {\n\t\tconst behavior = userBehaviorRef.current\n\t\tconst timeFactor = Math.min(behavior.timeOnPage / 60000, 1) // Cap at 1 minute\n\t\tconst interactionFactor = Math.min(\n\t\t\t(behavior.mouseMovements + behavior.scrollEvents + behavior.keyPresses) / 100,\n\t\t\t1\n\t\t)\n\n\t\treturn (timeFactor * 0.4 + interactionFactor * 0.6) * 100\n\t}, [])\n\n\t// Update user behavior tracking\n\tconst updateUserBehavior = useCallback(\n\t\t(type: keyof UserBehaviorData, increment = 1) => {\n\t\t\tconst behavior = userBehaviorRef.current\n\t\t\tbehavior[type] = typeof behavior[type] === \"number\" ? behavior[type] + increment : Date.now()\n\t\t\tbehavior.engagementScore = calculateEngagementScore()\n\t\t\tbehavior.lastInteraction = Date.now()\n\t\t},\n\t\t[calculateEngagementScore]\n\t)\n\n\t// Get current network conditions\n\tconst getNetworkConditions = useCallback(() => {\n\t\tif (!networkInfoRef.current || !adaptToNetwork) {\n\t\t\treturn { type: \"unknown\", downlink: 10, effectiveType: \"4g\", saveData: false }\n\t\t}\n\n\t\tconst network = networkInfoRef.current\n\t\treturn {\n\t\t\ttype: network.type,\n\t\t\tdownlink: network.downlink || 10,\n\t\t\teffectiveType: network.effectiveType || \"4g\",\n\t\t\tsaveData: network.saveData || false,\n\t\t\trtt: network.rtt || 100\n\t\t}\n\t}, [adaptToNetwork])\n\n\t// Determine if a source should be preloaded\n\tconst shouldPreloadSource = useCallback(\n\t\t(source: MediaSource, index: number, currentIndex: number = 0): PreloadingDecision => {\n\t\t\t// Skip if already preloaded\n\t\t\tif (preloadedItemsRef.current.has(source.src)) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Already preloaded\" }\n\t\t\t}\n\n\t\t\t// Check if within preload radius\n\t\t\tconst distance = Math.abs(index - currentIndex)\n\t\t\tif (distance > preloadRadius) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Outside preload radius\" }\n\t\t\t}\n\n\t\t\tconst behavior = userBehaviorRef.current\n\t\t\tconst network = getNetworkConditions()\n\t\t\tconst engagementScore = behavior.engagementScore\n\t\t\tconst timeSinceInteraction = Date.now() - behavior.lastInteraction\n\n\t\t\t// Network-based decisions\n\t\t\tif (network.saveData) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Data saver mode\" }\n\t\t\t}\n\n\t\t\t// Strategy-based filtering\n\t\t\tlet shouldPreload = false\n\t\t\tlet priority: \"high\" | \"medium\" | \"low\" = \"medium\"\n\t\t\tlet reason = \"\"\n\n\t\t\tswitch (strategy) {\n\t\t\t\tcase \"conservative\":\n\t\t\t\t\tshouldPreload = engagementScore > 70 && network.effectiveType !== \"2g\" && distance === 1\n\t\t\t\t\tpriority = shouldPreload ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload ? \"High engagement and optimal network\" : \"Conservative strategy\"\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"aggressive\":\n\t\t\t\t\tshouldPreload = engagementScore > 30 && network.effectiveType !== \"slow-2g\"\n\t\t\t\t\tpriority = engagementScore > 70 ? \"high\" : engagementScore > 50 ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload ? \"Aggressive preloading\" : \"Low engagement\"\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"balanced\":\n\t\t\t\tdefault:\n\t\t\t\t\tconst networkMultiplier =\n\t\t\t\t\t\tnetwork.effectiveType === \"4g\" ? 1 : network.effectiveType === \"3g\" ? 0.7 : 0.3\n\t\t\t\t\tconst adjustedScore = engagementScore * networkMultiplier\n\n\t\t\t\t\tshouldPreload = adjustedScore > 40 && distance <= 2\n\t\t\t\t\tpriority = adjustedScore > 70 ? \"high\" : adjustedScore > 55 ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload\n\t\t\t\t\t\t? `Balanced: score ${adjustedScore.toFixed(1)}`\n\t\t\t\t\t\t: \"Low adjusted score\"\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Additional heuristics\n\t\t\tif (shouldPreload) {\n\t\t\t\t// Prioritize HLS and adaptive streaming\n\t\t\t\tif (source.type === \"hls\" || source.type === \"m3u8\") {\n\t\t\t\t\tpriority = priority === \"low\" ? \"medium\" : \"high\"\n\t\t\t\t}\n\n\t\t\t\t// Boost priority for recent user interaction\n\t\t\t\tif (timeSinceInteraction < 5000) {\n\t\t\t\t\t// Within 5 seconds\n\t\t\t\t\tpriority = \"high\"\n\t\t\t\t\treason += \" + Recent interaction\"\n\t\t\t\t}\n\n\t\t\t\t// Consider content type (video gets higher priority than audio)\n\t\t\t\tif (source.type === \"mp4\" || source.type === \"webm\") {\n\t\t\t\t\tpriority = priority === \"low\" ? \"medium\" : priority\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { shouldPreload, priority, reason }\n\t\t},\n\t\t[strategy, preloadRadius, getNetworkConditions, calculateEngagementScore]\n\t)\n\n\t// Preload a specific source\n\tconst preloadSource = useCallback(async (source: MediaSource, priority: number) => {\n\t\ttry {\n\t\t\t// Create a preload link element\n\t\t\tconst link = document.createElement(\"link\")\n\t\t\tlink.rel = \"preload\"\n\t\t\tlink.href = source.src\n\n\t\t\t// Determine the correct 'as' attribute\n\t\t\tswitch (source.type) {\n\t\t\t\tcase \"hls\":\n\t\t\t\tcase \"m3u8\":\n\t\t\t\t\tlink.as = \"fetch\"\n\t\t\t\t\tbreak\n\t\t\t\tcase \"mp4\":\n\t\t\t\tcase \"webm\":\n\t\t\t\t\tlink.as = \"video\"\n\t\t\t\t\tbreak\n\t\t\t\tcase \"mp3\":\n\t\t\t\tcase \"wav\":\n\t\t\t\tcase \"ogg\":\n\t\t\t\t\tlink.as = \"audio\"\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tlink.as = \"fetch\"\n\t\t\t}\n\n\t\t\tlink.crossOrigin = \"anonymous\"\n\n\t\t\t// Add to document head\n\t\t\tdocument.head.appendChild(link)\n\n\t\t\t// Mark as preloaded\n\t\t\tpreloadedItemsRef.current.add(source.src)\n\n\t\t\tconsole.debug(`Preloaded: ${source.src} (${priority})`)\n\n\t\t\t// Cleanup after 30 seconds to prevent memory issues\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (document.head.contains(link)) {\n\t\t\t\t\tdocument.head.removeChild(link)\n\t\t\t\t}\n\t\t\t}, 30000)\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Failed to preload source:\", source.src, error)\n\t\t}\n\t}, [])\n\n\t// Process preload queue\n\tconst processPreloadQueue = useCallback(() => {\n\t\tif (preloadQueueRef.current.length === 0) return\n\n\t\t// Sort by priority (higher number = higher priority)\n\t\tconst sortedQueue = [...preloadQueueRef.current].sort((a, b) => b.priority - a.priority)\n\n\t\t// Take top items based on maxPreloadItems\n\t\tconst itemsToPreload = sortedQueue.slice(0, maxPreloadItems)\n\n\t\t// Clear queue\n\t\tpreloadQueueRef.current = []\n\n\t\t// Preload items\n\t\titemsToPreload.forEach(({ source, priority }) => {\n\t\t\tpreloadSource(source, priority)\n\t\t})\n\t}, [maxPreloadItems, preloadSource])\n\n\t// Update preloading decisions\n\tconst updatePreloading = useCallback(\n\t\t(currentIndex: number = 0) => {\n\t\t\tpreloadQueueRef.current = []\n\n\t\t\tsources.forEach((source, index) => {\n\t\t\t\tconst decision = shouldPreloadSource(source, index, currentIndex)\n\n\t\t\t\tif (decision.shouldPreload) {\n\t\t\t\t\tconst priority = decision.priority === \"high\" ? 3 : decision.priority === \"medium\" ? 2 : 1\n\n\t\t\t\t\tpreloadQueueRef.current.push({ source, priority })\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tprocessPreloadQueue()\n\t\t},\n\t\t[sources, shouldPreloadSource, processPreloadQueue]\n\t)\n\n\t// Set up user behavior tracking\n\tuseEffect(() => {\n\t\tif (!trackUserBehavior) return\n\n\t\tconst handleMouseMove = () => updateUserBehavior(\"mouseMovements\")\n\t\tconst handleScroll = () => updateUserBehavior(\"scrollEvents\")\n\t\tconst handleKeyPress = () => updateUserBehavior(\"keyPresses\")\n\t\tconst handleFocus = () => updateUserBehavior(\"focusEvents\")\n\n\t\t// Add event listeners\n\t\tdocument.addEventListener(\"mousemove\", handleMouseMove, { passive: true })\n\t\tdocument.addEventListener(\"scroll\", handleScroll, { passive: true })\n\t\tdocument.addEventListener(\"keydown\", handleKeyPress, { passive: true })\n\t\tdocument.addEventListener(\"focusin\", handleFocus, { passive: true })\n\n\t\t// Update time on page every second\n\t\tconst timeInterval = setInterval(() => {\n\t\t\tupdateUserBehavior(\"timeOnPage\", 1)\n\t\t}, 1000)\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousemove\", handleMouseMove)\n\t\t\tdocument.removeEventListener(\"scroll\", handleScroll)\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyPress)\n\t\t\tdocument.removeEventListener(\"focusin\", handleFocus)\n\t\t\tclearInterval(timeInterval)\n\t\t}\n\t}, [trackUserBehavior, updateUserBehavior])\n\n\t// Set up network monitoring\n\tuseEffect(() => {\n\t\tif (!adaptToNetwork || !(\"connection\" in navigator)) return\n\n\t\tconst network = (navigator as any).connection\n\t\tnetworkInfoRef.current = network\n\n\t\tconst handleNetworkChange = () => {\n\t\t\t// Re-evaluate preloading when network conditions change\n\t\t\tupdatePreloading()\n\t\t}\n\n\t\tnetwork.addEventListener(\"change\", handleNetworkChange)\n\n\t\treturn () => {\n\t\t\tnetwork.removeEventListener(\"change\", handleNetworkChange)\n\t\t}\n\t}, [adaptToNetwork, updatePreloading])\n\n\t// Initial preloading\n\tuseEffect(() => {\n\t\tupdatePreloading()\n\t}, [updatePreloading])\n\n\t// Memoize return values\n\tconst controls = useMemo(\n\t\t() => ({\n\t\t\t/**\n\t\t\t * Manually trigger preloading for specific index\n\t\t\t */\n\t\t\tpreloadAtIndex: (index: number) => {\n\t\t\t\tupdatePreloading(index)\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get current user behavior data\n\t\t\t */\n\t\t\tgetUserBehavior: () => ({ ...userBehaviorRef.current }),\n\n\t\t\t/**\n\t\t\t * Get current network conditions\n\t\t\t */\n\t\t\tgetNetworkConditions: getNetworkConditions,\n\n\t\t\t/**\n\t\t\t * Clear preloaded items cache\n\t\t\t */\n\t\t\tclearCache: () => {\n\t\t\t\tpreloadedItemsRef.current.clear()\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get preloading statistics\n\t\t\t */\n\t\t\tgetStats: () => ({\n\t\t\t\tpreloadedItems: preloadedItemsRef.current.size,\n\t\t\t\tengagementScore: userBehaviorRef.current.engagementScore,\n\t\t\t\tqueueLength: preloadQueueRef.current.length,\n\t\t\t\tmaxPreloadItems\n\t\t\t})\n\t\t}),\n\t\t[updatePreloading, getNetworkConditions, maxPreloadItems]\n\t)\n\n\treturn controls\n}\n\nexport default useIntelligentPreloading\n","import { useCallback, useEffect, useMemo, useState } from \"react\"\n\ninterface SubtitleCue {\n\tstart: number\n\tend: number\n\ttext: string\n}\n\nexport function useSubtitles(subtitleSrc?: string) {\n\tconst [subtitlesEnabled, setSubtitlesEnabled] = useState(false)\n\tconst [subtitleCues, setSubtitleCues] = useState<SubtitleCue[]>([])\n\tconst [currentSubtitle, setCurrentSubtitle] = useState(\"\")\n\n\tconst parseVTTTime = (timeStr: string): number => {\n\t\tconst parts = timeStr.split(\":\")\n\t\tconst seconds = parts[2] ? parseFloat(parts[2]) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds\n\t}\n\n\tconst loadSubtitles = async (url: string) => {\n\t\ttry {\n\t\t\tconst response = await fetch(url)\n\t\t\tconst text = await response.text()\n\n\t\t\tconst cues: SubtitleCue[] = []\n\t\t\tconst lines = text.split(\"\\n\")\n\t\t\tlet i = 0\n\n\t\t\twhile (i < lines.length) {\n\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\tconst start = parseVTTTime(startStr || \"\")\n\t\t\t\t\tconst end = parseVTTTime(endStr || \"\")\n\n\t\t\t\t\ti++\n\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\ti++\n\t\t\t\t\t}\n\n\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tsetSubtitleCues(cues)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to load subtitles:\", error)\n\t\t}\n\t}\n\n\tconst getCurrentSubtitle = (currentTime: number) => {\n\t\tif (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n\n\t\tconst currentCue = subtitleCues.find(\n\t\t\t(cue) => currentTime >= cue.start && currentTime <= cue.end\n\t\t)\n\t\treturn currentCue?.text || \"\"\n\t}\n\n\tconst toggleSubtitles = () => {\n\t\tsetSubtitlesEnabled((prev) => {\n\t\t\tconst newEnabled = !prev\n\t\t\tif (newEnabled && subtitleSrc && subtitleCues.length === 0) {\n\t\t\t\tloadSubtitles(subtitleSrc)\n\t\t\t} else if (!newEnabled) {\n\t\t\t\tsetCurrentSubtitle(\"\")\n\t\t\t}\n\t\t\treturn newEnabled\n\t\t})\n\t}\n\n\tuseEffect(() => {\n\t\tif (!subtitlesEnabled) {\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t}\n\t}, [subtitlesEnabled])\n\n\treturn {\n\t\tsubtitlesEnabled,\n\t\tcurrentSubtitle,\n\t\ttoggleSubtitles,\n\t\tgetCurrentSubtitle,\n\t\tsetCurrentSubtitle\n\t}\n}\n","/**\n * Legacy Hooks (Deprecated)\n * These hooks are wrapped with deprecation warnings\n */\n\nimport { showDeprecationWarning } from \"../lib/deprecation\"\n\n// Import current hooks\nimport { useMediaPlayer } from \"./use-media-player\"\nimport { useSubtitles } from \"./useSubtitles\"\n\n// Legacy hook wrappers with deprecation warnings\nexport function useVideoPlayer(props: any) {\n\tshowDeprecationWarning(\"useVideoPlayer\", \"useMediaPlayer (the primary media player hook)\")\n\treturn useMediaPlayer(props)\n}\n\nexport function useEnhancedSubtitles(props: any) {\n\tshowDeprecationWarning(\"useEnhancedSubtitles\", \"useSubtitles (the current subtitle hook)\")\n\treturn useSubtitles(props)\n}\n"],"names":["createOptimisticAction","type","store","payload","optimistic","action","useMediaActionState","actionState","setActionState","React","newActionState","current","useMediaActions","actions","MediaActionTypes","optimisticActions","isPlaying","time","delta","currentVolume","newVolume","isFullscreen","retryLastAction","lastAction","optimisticMediaReducer","state","useMediaOptimistic","actualState","optimisticState","addOptimistic","useOptimistic","dispatchOptimistic","volume","rate","selectors","formatTime","seconds","mins","secs","hours","useEnhancedMediaPlayer","options","mediaRef","useRef","containerRef","isPending","startTransition","useTransition","isSeeking","startSeekTransition","frameCount","lastFrameTime","lastTimeUpdate","useMediaStore","isEnhanced","useMediaSelector","currentTime","duration","isMuted","isLoading","isBuffering","error","buffered","enhancedStore","performanceMetrics","setPerformanceMetrics","optimisticVolume","setOptimisticVolume","newTime","useEffect","media","initProps","key","value","handleTimeUpdate","useCallback","now","handlePlay","handlePause","handleVolumeChange","handleSeeking","handleSeeked","handleProgress","measureRenderTime","fps","prev","eventListeners","event","handler","passive","rafId","performanceLoop","controls","useMemo","play","pause","clampedTime","clampedVolume","container","computedState","useKeyboardControls","enabled","seekStep","volumeStep","handleKeyDown","target","percentage","useMemoryOptimization","maxMemoryUsage","cleanupInterval","enableGC","monitorMemory","observersRef","eventListenersRef","intervalRefs","animationFrameRefs","getMemoryUsage","memory","memoryStats","setMemoryStats","performCleanup","timeout","frameId","observer","listeners","element","useInterval","callback","delay","timeoutId","checkMemory","usage","isHighUsage","addEventListener","index","l","setTimeout","requestAnimationFrame","addObserver","bytes","k","sizes","i","useMediaState","setState","useState","updateState","updates","useMediaPlayer","setPlaying","setCurrentTime","setDuration","setVolume","setMuted","setLoading","setFullscreen","setError","setBuffered","handleDurationChange","handleLoadStart","handleLoadedData","handleError","errorMessage","handleEnded","toggle","seek","setVolumeControl","mute","unmute","toggleMute","enterFullscreen","exitFullscreen","toggleFullscreen","handleFullscreenChange","BREAKPOINTS","detectPlatform","userAgent","isTouchDevice","supportsHaptics","useDeviceInfo","deviceInfo","setDeviceInfo","width","height","updateDeviceInfo","mobileQuery","tabletQuery","desktopQuery","useMobileOptimizations","platform","isMobile","preventZoom","e","useHapticFeedback","pattern","defaultConfig","useTouchGestures","ref","onGesture","config","mergedConfig","triggerHaptic","gestureState","getTouchPoint","touch","getDistance","p1","p2","getVelocity","start","end","timeDiff","createGestureEvent","startPoint","currentPoint","additionalData","handleTouchStart","touches","gestureEvent","handleTouchMove","currentDistance","scale","gestureType","centerPoint","startCenterPoint","startTouch","currentTouch","handleTouchEnd","endTouches","endTouch","distance","velocity","absVelX","absVelY","useMediaGestures","handleGesture","backwardAmount","forwardAmount","volumeAmount","useEnhancedSubtitles","subtitleSrc","subtitleTracks","defaultFontSize","onLoadError","subtitlesEnabled","setSubtitlesEnabled","subtitleCues","setSubtitleCues","currentSubtitle","setCurrentSubtitle","currentTrackId","setCurrentTrackId","fontSize","setFontSize","loadError","setLoadError","setIsLoading","sizeMap","hasSubtitles","parseVTTTime","timeStr","parts","minutes","parseSRTTime","ms","milliseconds","loadSubtitles","url","response","text","cues","lines","isVTT","isSRT","startStr","endStr","s","subtitleText","err","getCurrentSubtitle","cue","toggleSubtitles","newEnabled","srcToLoad","selectSubtitleTrack","trackId","track","t","changeSubtitleFontSize","size","getSubtitleStyles","useKeyboardShortcuts","videoControls","takeScreenshot","video","useMediaControls","showSettings","controlsVisible","setControlsVisible","showVolumeSlider","setShowVolumeSlider","hideTimeoutRef","showControls","handleMouseMove","handleMouseEnter","handleMouseLeave","useScreenshot","videoRef","ctrlKey","canvas","ctx","blob","item","a","useVideoPlayer","handleLoadedMetadata","handleWaiting","handlePlaying","handleCanPlay","ranges","useIntelligentPreloading","sources","trackUserBehavior","adaptToNetwork","strategy","maxPreloadItems","preloadRadius","userBehaviorRef","networkInfoRef","preloadedItemsRef","preloadQueueRef","calculateEngagementScore","behavior","timeFactor","interactionFactor","updateUserBehavior","increment","getNetworkConditions","network","shouldPreloadSource","source","currentIndex","engagementScore","timeSinceInteraction","shouldPreload","priority","reason","networkMultiplier","adjustedScore","preloadSource","link","processPreloadQueue","itemsToPreload","b","updatePreloading","decision","handleScroll","handleKeyPress","handleFocus","timeInterval","handleNetworkChange","useSubtitles","props","showDeprecationWarning"],"mappings":"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"}