@zuude-ui/video 0.1.32 → 0.1.34

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.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";"use client";var mt=Object.create;var K=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var dt=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var Et=(t,n)=>{for(var r in n)K(t,r,{get:n[r],enumerable:!0})},Z=(t,n,r,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let u of pt(n))!yt.call(t,u)&&u!==r&&K(t,u,{get:()=>n[u],enumerable:!(e=it(n,u))||e.enumerable});return t};var w=(t,n,r)=>(r=t!=null?mt(dt(t)):{},Z(n||!t||!t.__esModule?K(r,"default",{value:t,enumerable:!0}):r,t)),ht=t=>Z(K({},"__esModule",{value:!0}),t);var qt={};Et(qt,{Controls:()=>wt,Download:()=>jt,ExitFullscreen:()=>At,Fullscreen:()=>Mt,Loading:()=>Dt,Mute:()=>Ct,Pause:()=>Tt,PictureInPicture:()=>Ht,Play:()=>xt,SeekBackward:()=>It,SeekForward:()=>St,Shadow:()=>Ot,Speed:()=>Ft,Unmute:()=>kt,Video:()=>X,VideoProvider:()=>R,useVideo:()=>h});module.exports=ht(qt);var x=w(require("react"),1),J=require("react/jsx-runtime"),v=(0,x.createContext)(null),R=x.default.memo(({children:t,config:n,onError:r,...e})=>{let[u,o]=(0,x.useState)({current:null}),[s,c]=(0,x.useState)(null),[y,a]=(0,x.useState)(!1),g=(0,x.useRef)(null);return(0,x.useEffect)(()=>{r==null||r(s)},[s]),(0,x.useEffect)(()=>{let m=g.current;if(m){let l=m.querySelectorAll("[data-zuude-hide-elements]"),i=m.querySelector("[data-zuude-video]");if(l){let C=null,j=3e3,b=!1,p=()=>{C&&(clearTimeout(C),C=null),C=setTimeout(()=>{b&&i&&!i.paused&&l.forEach(k=>{k.setAttribute("data-hidden","true")}),C=null},j)},E=()=>{b=!0,l.forEach(k=>{k.removeAttribute("data-hidden")}),p()},A=()=>{b=!1,C&&(clearTimeout(C),C=null),i&&!i.paused&&l.forEach(k=>{k.setAttribute("data-hidden","true")})},P=()=>{b&&(l.forEach(k=>{k.hasAttribute("data-hidden")&&k.removeAttribute("data-hidden")}),p())},L=()=>{b||l.forEach(k=>{k.setAttribute("data-hidden","true")})};return m.addEventListener("mouseenter",E),m.addEventListener("mouseleave",A),m.addEventListener("mousemove",P),i.addEventListener("pause",E),i.addEventListener("play",L),()=>{C&&clearTimeout(C),m.removeEventListener("mouseenter",E),m.removeEventListener("mouseleave",A),m.removeEventListener("mousemove",P),i.removeEventListener("pause",E),i.removeEventListener("play",L)}}}},[]),(0,x.useEffect)(()=>{if(y){let m=l=>{var i;(i=g.current)!=null&&i.contains(l.target)||a(!1)};return document.addEventListener("click",m),()=>{document.removeEventListener("click",m)}}},[y]),(0,J.jsx)(v.Provider,{value:{videoRef:u,setVideoRef:o,config:{clickToPlay:!0,...n},error:s,setError:c,isFocused:y,setIsFocused:a},children:(0,J.jsx)("div",{ref:g,"data-zuude-video-wrapper":!0,onClick:()=>a(!0),...e,children:t})})}),h=()=>{let t=(0,x.useContext)(v);if(!t)throw new Error("useVideo must be used within a VideoProvider");return t};var M=require("react");var tt=w(require("react"),1),et=(t,n,r)=>{tt.default.useEffect(()=>{if(!(t!=null&&t.current)||!n)return;(async()=>{var u;try{await((u=t.current)==null?void 0:u.play())}catch(o){if(o instanceof Error&&o.name==="NotAllowedError"){if(r==null||r("NotAllowedError"),console.error("NotAllowedError"),t!=null&&t.current){t.current.muted=!0;try{await t.current.play()}catch(s){console.error(s)}}}else console.error(o)}})()},[n,t==null?void 0:t.current])};var rt=require("react"),D=(t,n,r=!0)=>{let e=u=>{u.key===t&&(u.preventDefault(),n(u))};(0,rt.useEffect)(()=>{if(r)return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[t,n,r])};var Q=w(require("react"),1),U=(t,n=10)=>{let r=Q.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime+=n)},[t==null?void 0:t.current]),e=Q.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime-=n)},[t==null?void 0:t.current]);return{seekForward:r,seekBackward:e}};var q=w(require("react"),1),B=t=>{let[n,r]=q.default.useState(!1),e=q.default.useCallback(()=>{t!=null&&t.current&&(t.current.paused?t.current.play():t.current.pause())},[t==null?void 0:t.current]),u=q.default.useCallback(()=>{t!=null&&t.current&&t.current.play()},[t==null?void 0:t.current]),o=q.default.useCallback(()=>{t!=null&&t.current&&t.current.pause()},[t==null?void 0:t.current]);return q.default.useEffect(()=>{if(!(t!=null&&t.current))return;let s=()=>{r(!0)},c=()=>{r(!1)};if(r(!(t!=null&&t.current.paused)),t!=null&&t.current)return t.current.addEventListener("play",s),t.current.addEventListener("pause",c),()=>{var y,a;(y=t.current)==null||y.removeEventListener("play",s),(a=t.current)==null||a.removeEventListener("pause",c)}},[t==null?void 0:t.current]),{togglePlay:e,isPlaying:n,play:u,pause:o}};var N=w(require("react"),1),W=t=>{let[n,r]=N.default.useState(!1),e=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!t.current.muted)},[t==null?void 0:t.current]),u=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!0)},[t==null?void 0:t.current]),o=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!1)},[t==null?void 0:t.current]);return N.default.useEffect(()=>{if(!(t!=null&&t.current))return;r(t.current.muted);let s=()=>{t.current&&r(t.current.muted)};return t.current.addEventListener("volumechange",s),()=>{var c;(c=t.current)==null||c.removeEventListener("volumechange",s)}},[t==null?void 0:t.current]),{toggleMute:e,isMuted:n,mute:u,unmute:o}};var $=w(require("react"),1),z=t=>{let[n,r]=$.default.useState(!1),e=$.default.useRef(null);$.default.useEffect(()=>{let o=()=>{let s=!!document.fullscreenElement;r(s);let c=t==null?void 0:t.current;c&&(s?(e.current={objectFit:c.style.objectFit||"cover",borderRadius:c.style.borderRadius||"",width:c.style.width||"",height:c.style.height||"",maxWidth:c.style.maxWidth||"",maxHeight:c.style.maxHeight||"",margin:c.style.margin||""},c.style.objectFit="contain",c.style.borderRadius="0",c.style.width="100%",c.style.height="100%",c.style.maxWidth="none",c.style.maxHeight="none",c.style.margin="0"):e.current&&(c.style.objectFit=e.current.objectFit,c.style.borderRadius=e.current.borderRadius,c.style.width=e.current.width,c.style.height=e.current.height,c.style.maxWidth=e.current.maxWidth,c.style.maxHeight=e.current.maxHeight,c.style.margin=e.current.margin,e.current=null))};return document.addEventListener("fullscreenchange",o),()=>document.removeEventListener("fullscreenchange",o)},[t]);let u=()=>{let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=t==null?void 0:t.current;if(s&&o){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let c=s==null?void 0:s.closest("[data-zuude-video-wrapper]");c&&(n?document.exitFullscreen():c.requestFullscreen())};return{isFullscreen:n!=null?n:!1,toggleFullscreen:u}};var G=t=>({togglePictureInPicture:async()=>{let u=t==null?void 0:t.current;if(u)try{document.pictureInPictureElement?await document.exitPictureInPicture():await u.requestPictureInPicture()}catch(o){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))u.webkitEnterFullscreen?u.webkitEnterFullscreen():u.requestFullscreen&&u.requestFullscreen();else{let c=u.closest("[data-zuude-video-wrapper]");c&&(document.fullscreenElement?await document.exitFullscreen():await c.requestFullscreen())}}},requestPictureInPicture:async()=>{let u=t==null?void 0:t.current;u&&await u.requestPictureInPicture()},exitPictureInPicture:async()=>{t!=null&&t.current&&await document.exitPictureInPicture()}});var nt=()=>{let{videoRef:t}=h(),{seekForward:n,seekBackward:r}=U(t),{togglePlay:e}=B(t),{toggleMute:u}=W(t),{toggleFullscreen:o}=z(t),{togglePictureInPicture:s}=G(t);return D("ArrowRight",()=>{n()}),D("ArrowLeft",()=>{r()}),D(" ",()=>{e()}),D("m",()=>{u()}),D("f",()=>{o()}),D("p",()=>{s()}),null};var ut=w(require("react"),1),st=(t,n,r=!0)=>{ut.default.useEffect(()=>{if(!(t!=null&&t.current)||!r)return;let e=new IntersectionObserver(u=>{u.forEach(o=>{var s;t!=null&&t.current&&(o.isIntersecting?t.current.play().catch(c=>{t.current&&(t.current.pause(),t.current.muted=!0,t.current.play(),console.error(c))}):(s=t.current)==null||s.pause())})},{threshold:n!=null?n:.5});return e.observe(t==null?void 0:t.current),()=>{e.disconnect()}},[t==null?void 0:t.current])};var gt=w(require("react"),1);var _=w(require("react"),1),ct=t=>{let[n,r]=_.default.useState(1),e=u=>{r(u)};return _.default.useEffect(()=>{t!=null&&t.current&&r(t.current.playbackRate)},[t==null?void 0:t.current]),_.default.useEffect(()=>{t!=null&&t.current&&(t.current.playbackRate=n)},[n,t==null?void 0:t.current]),{speed:n,onChangeSpeed:e}};var bt=w(require("react"),1);var Pt=w(require("react"),1);var ot=require("react");var Lt=w(require("react"),1);var Vt=w(require("react"),1);var H=require("react"),at=t=>{let[n,r]=(0,H.useState)(!1),[e,u]=(0,H.useState)(0),[o,s]=(0,H.useState)(null),c=(0,H.useCallback)(async a=>{var l;if(!(t!=null&&t.current)){s("Video element not found");return}let g=t.current,m=g.src||g.currentSrc;if(!m){s("No video source found");return}try{r(!0),s(null),u(0);let i=await fetch(m);if(!i.ok)throw new Error(`Failed to fetch video: ${i.statusText}`);let C=i.headers.get("content-length"),j=C?parseInt(C,10):0,b=(l=i.body)==null?void 0:l.getReader();if(!b)throw new Error("Failed to create download stream");let p=[],E=0;for(;;){let{done:f,value:d}=await b.read();if(f)break;if(p.push(d),E+=d.length,j>0){let F=E/j*100;u(Math.round(F))}}let A=new Blob(p,{type:i.headers.get("content-type")||"video/mp4"}),P=URL.createObjectURL(A),L=document.createElement("a");L.href=P;let k=a||`video-${Date.now()}.mp4`;L.download=k,document.body.appendChild(L),L.click(),document.body.removeChild(L),URL.revokeObjectURL(P),u(100),r(!1)}catch(i){s(i instanceof Error?i.message:"Download failed"),r(!1),u(0)}},[t]),y=(0,H.useCallback)(a=>{if(!(t!=null&&t.current)){s("Video element not found");return}let g=t.current,m=g.src||g.currentSrc;if(!m){s("No video source found");return}try{r(!0),s(null),u(0);let l=document.createElement("a");l.href=m,l.download=a||`video-${Date.now()}.mp4`,l.target="_blank",document.body.appendChild(l),l.click(),document.body.removeChild(l),r(!1),u(100)}catch(l){s(l instanceof Error?l.message:"Download failed"),r(!1),u(0)}},[t]);return(0,H.useEffect)(()=>()=>{r(!1),u(0),s(null)},[]),{downloadVideo:c,downloadDirect:y,isDownloading:n,downloadProgress:e,error:o,resetError:()=>s(null)}};var ft=w(require("react"),1);var O=require("react/jsx-runtime"),X=(0,M.forwardRef)(({src:t,autoPlay:n,muteFallback:r,controls:e,preload:u="metadata",autoPlayOnVisible:o,ranges:s,...c},y)=>{let{videoRef:a,setVideoRef:g,config:m,setError:l,error:i,isFocused:C}=h(),j=(0,M.useRef)(null),b=(0,M.useRef)(!1),p=(0,M.useRef)(null),E=(0,M.useRef)(null),A=s&&s.length>=2&&typeof s[0]=="number"&&typeof s[1]=="number"&&s[0]>=0&&s[1]>s[0]&&isFinite(s[0])&&isFinite(s[1]),P=A?s[0]:void 0,L=A?s[1]:void 0;(0,M.useEffect)(()=>{let f=j.current,d=y;return d?g(d):f&&g({current:f}),()=>{b.current=!1,p.current!==null&&(cancelAnimationFrame(p.current),p.current=null),E.current!==null&&(clearTimeout(E.current),E.current=null)}},[t,y,g]),(0,M.useEffect)(()=>()=>{p.current!==null&&(cancelAnimationFrame(p.current),p.current=null),E.current!==null&&(clearTimeout(E.current),E.current=null)},[]),et(a,n==="force"&&c.muted===void 0,l),st(a,typeof o=="number"?o:o?void 0:.5,!!o);let k=(0,M.useCallback)(()=>{var f,d,F;(f=a==null?void 0:a.current)!=null&&f.paused?(d=a.current)==null||d.play():(F=a==null?void 0:a.current)==null||F.pause()},[a]);return(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)("video",{ref:y||j,"data-zuude-video":!0,src:t,onClick:m!=null&&m.clickToPlay?k:void 0,autoPlay:n==="force"?!0:n,preload:u,playsInline:!0,onCanPlay:f=>{var F;let d=f.currentTarget;if(A&&P!==void 0&&L!==void 0&&d.paused){let I=d.currentTime;(I<P||I>L)&&(d.currentTime=P)}(F=c.onCanPlay)==null||F.call(c,f)},onSeeked:f=>{var F;let d=f.currentTarget;if(A&&P!==void 0&&L!==void 0&&d.paused){let I=d.currentTime;if((I<P||I>L)&&Math.abs(I-P)>.01){b.current=!0,d.currentTime=P,p.current!==null&&cancelAnimationFrame(p.current),p.current=requestAnimationFrame(()=>{b.current=!1,p.current=null});return}}b.current=!1,(F=c.onSeeked)==null||F.call(c,f)},onTimeUpdate:f=>{var F;let d=f.currentTarget;if(A&&P!==void 0&&L!==void 0&&!b.current){let I=d.currentTime;!d.paused&&I>=L?(b.current=!0,d.currentTime=P,E.current!==null&&clearTimeout(E.current),p.current=requestAnimationFrame(()=>{E.current=setTimeout(()=>{b.current&&(b.current=!1),E.current=null},100),p.current=null})):d.paused&&(I<P||I>L)&&(Math.abs(I-P)>.01||I>L)&&(b.current=!0,d.currentTime=P,p.current!==null&&cancelAnimationFrame(p.current),E.current!==null&&clearTimeout(E.current),p.current=requestAnimationFrame(()=>{b.current=!1,p.current=null}))}(F=c.onTimeUpdate)==null||F.call(c,f)},...c}),e&&C&&(0,O.jsx)(nt,{}),i==="NotAllowedError"&&typeof r=="function"&&r(()=>{a!=null&&a.current&&(a.current.muted=!a.current.muted),l(null)})]})});X.displayName="Video";var V=w(require("react"),1),S=require("@radix-ui/react-slot");var Y=w(require("react"),1),lt=t=>{let[n,r]=Y.default.useState(!1);return Y.default.useEffect(()=>{if(!(t!=null&&t.current))return;let e=t.current,u=()=>{r(!0)},o=()=>{},s=()=>{},c=()=>{r(!1)},y=()=>{r(!1)},a=()=>{r(!0)},g=()=>{r(!1)},m=()=>{r(!1)},l=()=>{r(!1)},i=()=>{};return e.addEventListener("loadstart",u),e.addEventListener("loadedmetadata",o),e.addEventListener("loadeddata",s),e.addEventListener("canplay",c),e.addEventListener("canplaythrough",y),e.addEventListener("waiting",a),e.addEventListener("playing",g),e.addEventListener("error",m),e.addEventListener("abort",l),e.addEventListener("suspend",i),e.readyState>=2&&r(!1),()=>{e.removeEventListener("loadstart",u),e.removeEventListener("loadedmetadata",o),e.removeEventListener("loadeddata",s),e.removeEventListener("canplay",c),e.removeEventListener("canplaythrough",y),e.removeEventListener("waiting",a),e.removeEventListener("playing",g),e.removeEventListener("error",m),e.removeEventListener("abort",l),e.removeEventListener("suspend",i)}},[t]),{isLoading:n}};var T=require("react/jsx-runtime"),wt=V.default.memo(({children:t,asChild:n,...r})=>(0,T.jsx)("div",{"data-zuude-hide-elements":!0,...r,children:t})),xt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{play:o}=B(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),Tt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{pause:o}=B(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),Ct=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{mute:o}=W(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),kt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{unmute:o}=W(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),Ft=V.default.memo(({children:t,asChild:n,value:r,onClick:e,...u})=>{let o=n?S.Slot:"button",{videoRef:s}=h(),{speed:c,onChangeSpeed:y}=ct(s);return(0,T.jsx)(o,{...u,value:r,onClick:()=>{y(r),e==null||e()},children:t})}),St=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{seekForward:o}=U(u,10);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),It=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{seekBackward:o}=U(u,10);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),Mt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{toggleFullscreen:o}=z(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),At=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{toggleFullscreen:o}=z(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),Ht=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{togglePictureInPicture:o}=G(u);return(0,T.jsx)(e,{...r,onClick:o,children:t})}),jt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=h(),{downloadDirect:o}=at(u);return(0,T.jsx)(e,{...r,onClick:()=>o(),children:t})}),Dt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"div",{videoRef:u}=h(),{isLoading:o}=lt(u);return(0,T.jsx)(e,{...r,style:{...r.style,pointerEvents:"none"},"data-loading":o,children:t})}),Ot=({...t})=>{let{videoRef:n}=h(),r=(0,V.useRef)(null);return V.default.useEffect(()=>{let e=n==null?void 0:n.current;if(r.current&&e){let u=0,o=!1,s=null,c=()=>{s&&clearInterval(s),s=setInterval(()=>{u=e.currentTime,r.current&&(r.current.currentTime=u)},100)},y=()=>{s&&(clearInterval(s),s=null)},a=()=>{o=!0,c()},g=()=>{o=!1,y()};return e.addEventListener("play",a),e.addEventListener("pause",g),()=>{y(),e.removeEventListener("play",a),e.removeEventListener("pause",g)}}},[n==null?void 0:n.current]),n!=null&&n.current?(0,T.jsx)("div",{...t,style:{...t.style,position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none"},children:(0,T.jsx)("video",{ref:r,src:n.current.src,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"cover"}})}):null};0&&(module.exports={Controls,Download,ExitFullscreen,Fullscreen,Loading,Mute,Pause,PictureInPicture,Play,SeekBackward,SeekForward,Shadow,Speed,Unmute,Video,VideoProvider,useVideo});
1
+ "use strict";"use client";var mt=Object.create;var K=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var pt=Object.getOwnPropertyNames;var dt=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var Et=(t,n)=>{for(var r in n)K(t,r,{get:n[r],enumerable:!0})},Z=(t,n,r,e)=>{if(n&&typeof n=="object"||typeof n=="function")for(let u of pt(n))!yt.call(t,u)&&u!==r&&K(t,u,{get:()=>n[u],enumerable:!(e=it(n,u))||e.enumerable});return t};var x=(t,n,r)=>(r=t!=null?mt(dt(t)):{},Z(n||!t||!t.__esModule?K(r,"default",{value:t,enumerable:!0}):r,t)),ht=t=>Z(K({},"__esModule",{value:!0}),t);var qt={};Et(qt,{Controls:()=>wt,Download:()=>jt,ExitFullscreen:()=>At,Fullscreen:()=>Mt,Loading:()=>Dt,Mute:()=>Ct,Pause:()=>Tt,PictureInPicture:()=>Ht,Play:()=>xt,SeekBackward:()=>It,SeekForward:()=>St,Shadow:()=>Ot,Speed:()=>Ft,Unmute:()=>kt,Video:()=>X,VideoProvider:()=>R,useVideo:()=>g});module.exports=ht(qt);var T=x(require("react"),1),J=require("react/jsx-runtime"),v=(0,T.createContext)(null),R=T.default.memo(({children:t,config:n,onError:r,...e})=>{let[u,o]=(0,T.useState)({current:null}),[s,c]=(0,T.useState)(null),[y,a]=(0,T.useState)(!1),b=(0,T.useRef)(null);return(0,T.useEffect)(()=>{r==null||r(s)},[s]),(0,T.useEffect)(()=>{let m=b.current;if(m){let l=m.querySelectorAll("[data-zuude-hide-elements]"),i=m.querySelector("[data-zuude-video]");if(l){let k=null,j=3e3,P=!1,d=()=>{k&&(clearTimeout(k),k=null),k=setTimeout(()=>{P&&i&&!i.paused&&l.forEach(F=>{F.setAttribute("data-hidden","true")}),k=null},j)},E=()=>{P=!0,l.forEach(F=>{F.removeAttribute("data-hidden")}),d()},A=()=>{P=!1,k&&(clearTimeout(k),k=null),i&&!i.paused&&l.forEach(F=>{F.setAttribute("data-hidden","true")})},h=()=>{P&&(l.forEach(F=>{F.hasAttribute("data-hidden")&&F.removeAttribute("data-hidden")}),d())},f=()=>{P||l.forEach(F=>{F.setAttribute("data-hidden","true")})};return m.addEventListener("mouseenter",E),m.addEventListener("mouseleave",A),m.addEventListener("mousemove",h),i.addEventListener("pause",E),i.addEventListener("play",f),()=>{k&&clearTimeout(k),m.removeEventListener("mouseenter",E),m.removeEventListener("mouseleave",A),m.removeEventListener("mousemove",h),i.removeEventListener("pause",E),i.removeEventListener("play",f)}}}},[]),(0,T.useEffect)(()=>{if(y){let m=l=>{var i;(i=b.current)!=null&&i.contains(l.target)||a(!1)};return document.addEventListener("click",m),()=>{document.removeEventListener("click",m)}}},[y]),(0,J.jsx)(v.Provider,{value:{videoRef:u,setVideoRef:o,config:{clickToPlay:!0,...n},error:s,setError:c,isFocused:y,setIsFocused:a},children:(0,J.jsx)("div",{ref:b,"data-zuude-video-wrapper":!0,onClick:()=>a(!0),...e,children:t})})}),g=()=>{let t=(0,T.useContext)(v);if(!t)throw new Error("useVideo must be used within a VideoProvider");return t};var M=require("react");var tt=x(require("react"),1),et=(t,n,r)=>{tt.default.useEffect(()=>{if(!(t!=null&&t.current)||!n)return;(async()=>{var u;try{await((u=t.current)==null?void 0:u.play())}catch(o){if(o instanceof Error&&o.name==="NotAllowedError"){if(r==null||r("NotAllowedError"),console.error("NotAllowedError"),t!=null&&t.current){t.current.muted=!0;try{await t.current.play()}catch(s){console.error(s)}}}else console.error(o)}})()},[n,t==null?void 0:t.current])};var rt=require("react"),D=(t,n,r=!0)=>{let e=u=>{u.key===t&&(u.preventDefault(),n(u))};(0,rt.useEffect)(()=>{if(r)return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[t,n,r])};var Q=x(require("react"),1),U=(t,n=10)=>{let r=Q.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime+=n)},[t==null?void 0:t.current]),e=Q.default.useCallback(()=>{t!=null&&t.current&&(t.current.currentTime-=n)},[t==null?void 0:t.current]);return{seekForward:r,seekBackward:e}};var q=x(require("react"),1),B=t=>{let[n,r]=q.default.useState(!1),e=q.default.useCallback(()=>{t!=null&&t.current&&(t.current.paused?t.current.play():t.current.pause())},[t==null?void 0:t.current]),u=q.default.useCallback(()=>{t!=null&&t.current&&t.current.play()},[t==null?void 0:t.current]),o=q.default.useCallback(()=>{t!=null&&t.current&&t.current.pause()},[t==null?void 0:t.current]);return q.default.useEffect(()=>{if(!(t!=null&&t.current))return;let s=()=>{r(!0)},c=()=>{r(!1)};if(r(!(t!=null&&t.current.paused)),t!=null&&t.current)return t.current.addEventListener("play",s),t.current.addEventListener("pause",c),()=>{var y,a;(y=t.current)==null||y.removeEventListener("play",s),(a=t.current)==null||a.removeEventListener("pause",c)}},[t==null?void 0:t.current]),{togglePlay:e,isPlaying:n,play:u,pause:o}};var N=x(require("react"),1),W=t=>{let[n,r]=N.default.useState(!1),e=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!t.current.muted)},[t==null?void 0:t.current]),u=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!0)},[t==null?void 0:t.current]),o=N.default.useCallback(()=>{t!=null&&t.current&&(t.current.muted=!1)},[t==null?void 0:t.current]);return N.default.useEffect(()=>{if(!(t!=null&&t.current))return;r(t.current.muted);let s=()=>{t.current&&r(t.current.muted)};return t.current.addEventListener("volumechange",s),()=>{var c;(c=t.current)==null||c.removeEventListener("volumechange",s)}},[t==null?void 0:t.current]),{toggleMute:e,isMuted:n,mute:u,unmute:o}};var $=x(require("react"),1),z=t=>{let[n,r]=$.default.useState(!1),e=$.default.useRef(null);$.default.useEffect(()=>{let o=()=>{let s=!!document.fullscreenElement;r(s);let c=t==null?void 0:t.current;c&&(s?(e.current={objectFit:c.style.objectFit||"cover",borderRadius:c.style.borderRadius||"",width:c.style.width||"",height:c.style.height||"",maxWidth:c.style.maxWidth||"",maxHeight:c.style.maxHeight||"",margin:c.style.margin||""},c.style.objectFit="contain",c.style.borderRadius="0",c.style.width="100%",c.style.height="100%",c.style.maxWidth="none",c.style.maxHeight="none",c.style.margin="0"):e.current&&(c.style.objectFit=e.current.objectFit,c.style.borderRadius=e.current.borderRadius,c.style.width=e.current.width,c.style.height=e.current.height,c.style.maxWidth=e.current.maxWidth,c.style.maxHeight=e.current.maxHeight,c.style.margin=e.current.margin,e.current=null))};return document.addEventListener("fullscreenchange",o),()=>document.removeEventListener("fullscreenchange",o)},[t]);let u=()=>{let o=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),s=t==null?void 0:t.current;if(s&&o){if(s.webkitEnterFullscreen){s.webkitEnterFullscreen();return}else if(s.requestFullscreen){s.requestFullscreen();return}}let c=s==null?void 0:s.closest("[data-zuude-video-wrapper]");c&&(n?document.exitFullscreen():c.requestFullscreen())};return{isFullscreen:n!=null?n:!1,toggleFullscreen:u}};var G=t=>({togglePictureInPicture:async()=>{let u=t==null?void 0:t.current;if(u)try{document.pictureInPictureElement?await document.exitPictureInPicture():await u.requestPictureInPicture()}catch(o){if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent))u.webkitEnterFullscreen?u.webkitEnterFullscreen():u.requestFullscreen&&u.requestFullscreen();else{let c=u.closest("[data-zuude-video-wrapper]");c&&(document.fullscreenElement?await document.exitFullscreen():await c.requestFullscreen())}}},requestPictureInPicture:async()=>{let u=t==null?void 0:t.current;u&&await u.requestPictureInPicture()},exitPictureInPicture:async()=>{t!=null&&t.current&&await document.exitPictureInPicture()}});var nt=()=>{let{videoRef:t}=g(),{seekForward:n,seekBackward:r}=U(t),{togglePlay:e}=B(t),{toggleMute:u}=W(t),{toggleFullscreen:o}=z(t),{togglePictureInPicture:s}=G(t);return D("ArrowRight",()=>{n()}),D("ArrowLeft",()=>{r()}),D(" ",()=>{e()}),D("m",()=>{u()}),D("f",()=>{o()}),D("p",()=>{s()}),null};var ut=x(require("react"),1),st=(t,n,r=!0)=>{ut.default.useEffect(()=>{if(!(t!=null&&t.current)||!r)return;let e=new IntersectionObserver(u=>{u.forEach(o=>{var s;t!=null&&t.current&&(o.isIntersecting?t.current.play().catch(c=>{t.current&&(t.current.pause(),t.current.muted=!0,t.current.play(),console.error(c))}):(s=t.current)==null||s.pause())})},{threshold:n!=null?n:.5});return e.observe(t==null?void 0:t.current),()=>{e.disconnect()}},[t==null?void 0:t.current])};var gt=x(require("react"),1);var _=x(require("react"),1),ct=t=>{let[n,r]=_.default.useState(1),e=u=>{r(u)};return _.default.useEffect(()=>{t!=null&&t.current&&r(t.current.playbackRate)},[t==null?void 0:t.current]),_.default.useEffect(()=>{t!=null&&t.current&&(t.current.playbackRate=n)},[n,t==null?void 0:t.current]),{speed:n,onChangeSpeed:e}};var bt=x(require("react"),1);var Pt=x(require("react"),1);var ot=require("react");var Lt=x(require("react"),1);var ft=x(require("react"),1);var H=require("react"),at=t=>{let[n,r]=(0,H.useState)(!1),[e,u]=(0,H.useState)(0),[o,s]=(0,H.useState)(null),c=(0,H.useCallback)(async a=>{var l;if(!(t!=null&&t.current)){s("Video element not found");return}let b=t.current,m=b.src||b.currentSrc;if(!m){s("No video source found");return}try{r(!0),s(null),u(0);let i=await fetch(m);if(!i.ok)throw new Error(`Failed to fetch video: ${i.statusText}`);let k=i.headers.get("content-length"),j=k?parseInt(k,10):0,P=(l=i.body)==null?void 0:l.getReader();if(!P)throw new Error("Failed to create download stream");let d=[],E=0;for(;;){let{done:L,value:p}=await P.read();if(L)break;if(d.push(p),E+=p.length,j>0){let w=E/j*100;u(Math.round(w))}}let A=new Blob(d,{type:i.headers.get("content-type")||"video/mp4"}),h=URL.createObjectURL(A),f=document.createElement("a");f.href=h;let F=a||`video-${Date.now()}.mp4`;f.download=F,document.body.appendChild(f),f.click(),document.body.removeChild(f),URL.revokeObjectURL(h),u(100),r(!1)}catch(i){s(i instanceof Error?i.message:"Download failed"),r(!1),u(0)}},[t]),y=(0,H.useCallback)(a=>{if(!(t!=null&&t.current)){s("Video element not found");return}let b=t.current,m=b.src||b.currentSrc;if(!m){s("No video source found");return}try{r(!0),s(null),u(0);let l=document.createElement("a");l.href=m,l.download=a||`video-${Date.now()}.mp4`,l.target="_blank",document.body.appendChild(l),l.click(),document.body.removeChild(l),r(!1),u(100)}catch(l){s(l instanceof Error?l.message:"Download failed"),r(!1),u(0)}},[t]);return(0,H.useEffect)(()=>()=>{r(!1),u(0),s(null)},[]),{downloadVideo:c,downloadDirect:y,isDownloading:n,downloadProgress:e,error:o,resetError:()=>s(null)}};var Vt=x(require("react"),1);var O=require("react/jsx-runtime"),X=(0,M.forwardRef)(({src:t,autoPlay:n,muteFallback:r,controls:e,preload:u="metadata",autoPlayOnVisible:o,ranges:s,...c},y)=>{let{videoRef:a,setVideoRef:b,config:m,setError:l,error:i,isFocused:k}=g(),j=(0,M.useRef)(null),P=(0,M.useRef)(!1),d=(0,M.useRef)(null),E=(0,M.useRef)(null),A=s&&s.length>=2&&typeof s[0]=="number"&&typeof s[1]=="number"&&s[0]>=0&&s[1]>s[0]&&isFinite(s[0])&&isFinite(s[1]),h=A?s[0]:void 0,f=A?s[1]:void 0;(0,M.useEffect)(()=>{let L=j.current,p=y;return p?b(p):L&&b({current:L}),()=>{P.current=!1,d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),E.current!==null&&(clearTimeout(E.current),E.current=null)}},[t,y,b]),(0,M.useEffect)(()=>()=>{d.current!==null&&(cancelAnimationFrame(d.current),d.current=null),E.current!==null&&(clearTimeout(E.current),E.current=null)},[]),et(a,n==="force"&&c.muted===void 0,l),st(a,typeof o=="number"?o:o?void 0:.5,!!o);let F=(0,M.useCallback)(()=>{var L,p,w;(L=a==null?void 0:a.current)!=null&&L.paused?(p=a.current)==null||p.play():(w=a==null?void 0:a.current)==null||w.pause()},[a]);return(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)("video",{ref:y||j,"data-zuude-video":!0,src:t,onClick:m!=null&&m.clickToPlay?F:void 0,autoPlay:n==="force"?!0:n,preload:u,playsInline:!0,onLoadedMetadata:L=>{var w;let p=L.currentTarget;A&&h!==void 0&&f!==void 0&&(p.currentTime=h),(w=c.onLoadedMetadata)==null||w.call(c,L)},onCanPlay:L=>{var w;let p=L.currentTarget;if(A&&h!==void 0&&f!==void 0){let I=p.currentTime;(I<h||I>f)&&(p.currentTime=h)}(w=c.onCanPlay)==null||w.call(c,L)},onSeeked:L=>{var w;let p=L.currentTarget;if(A&&h!==void 0&&f!==void 0&&p.paused){let I=p.currentTime;if((I<h||I>f)&&Math.abs(I-h)>.01){P.current=!0,p.currentTime=h,d.current!==null&&cancelAnimationFrame(d.current),d.current=requestAnimationFrame(()=>{P.current=!1,d.current=null});return}}P.current=!1,(w=c.onSeeked)==null||w.call(c,L)},onTimeUpdate:L=>{var w;let p=L.currentTarget;if(A&&h!==void 0&&f!==void 0&&!P.current){let I=p.currentTime;!p.paused&&I>=f?(P.current=!0,p.currentTime=h,E.current!==null&&clearTimeout(E.current),d.current=requestAnimationFrame(()=>{E.current=setTimeout(()=>{P.current&&(P.current=!1),E.current=null},100),d.current=null})):p.paused&&(I<h||I>f)&&(Math.abs(I-h)>.01||I>f)&&(P.current=!0,p.currentTime=h,d.current!==null&&cancelAnimationFrame(d.current),E.current!==null&&clearTimeout(E.current),d.current=requestAnimationFrame(()=>{P.current=!1,d.current=null}))}(w=c.onTimeUpdate)==null||w.call(c,L)},...c}),e&&k&&(0,O.jsx)(nt,{}),i==="NotAllowedError"&&typeof r=="function"&&r(()=>{a!=null&&a.current&&(a.current.muted=!a.current.muted),l(null)})]})});X.displayName="Video";var V=x(require("react"),1),S=require("@radix-ui/react-slot");var Y=x(require("react"),1),lt=t=>{let[n,r]=Y.default.useState(!1);return Y.default.useEffect(()=>{if(!(t!=null&&t.current))return;let e=t.current,u=()=>{r(!0)},o=()=>{},s=()=>{},c=()=>{r(!1)},y=()=>{r(!1)},a=()=>{r(!0)},b=()=>{r(!1)},m=()=>{r(!1)},l=()=>{r(!1)},i=()=>{};return e.addEventListener("loadstart",u),e.addEventListener("loadedmetadata",o),e.addEventListener("loadeddata",s),e.addEventListener("canplay",c),e.addEventListener("canplaythrough",y),e.addEventListener("waiting",a),e.addEventListener("playing",b),e.addEventListener("error",m),e.addEventListener("abort",l),e.addEventListener("suspend",i),e.readyState>=2&&r(!1),()=>{e.removeEventListener("loadstart",u),e.removeEventListener("loadedmetadata",o),e.removeEventListener("loadeddata",s),e.removeEventListener("canplay",c),e.removeEventListener("canplaythrough",y),e.removeEventListener("waiting",a),e.removeEventListener("playing",b),e.removeEventListener("error",m),e.removeEventListener("abort",l),e.removeEventListener("suspend",i)}},[t]),{isLoading:n}};var C=require("react/jsx-runtime"),wt=V.default.memo(({children:t,asChild:n,...r})=>(0,C.jsx)("div",{"data-zuude-hide-elements":!0,...r,children:t})),xt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{play:o}=B(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),Tt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{pause:o}=B(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),Ct=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{mute:o}=W(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),kt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{unmute:o}=W(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),Ft=V.default.memo(({children:t,asChild:n,value:r,onClick:e,...u})=>{let o=n?S.Slot:"button",{videoRef:s}=g(),{speed:c,onChangeSpeed:y}=ct(s);return(0,C.jsx)(o,{...u,value:r,onClick:()=>{y(r),e==null||e()},children:t})}),St=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{seekForward:o}=U(u,10);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),It=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{seekBackward:o}=U(u,10);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),Mt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{toggleFullscreen:o}=z(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),At=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{toggleFullscreen:o}=z(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),Ht=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{togglePictureInPicture:o}=G(u);return(0,C.jsx)(e,{...r,onClick:o,children:t})}),jt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"button",{videoRef:u}=g(),{downloadDirect:o}=at(u);return(0,C.jsx)(e,{...r,onClick:()=>o(),children:t})}),Dt=V.default.memo(({children:t,asChild:n,...r})=>{let e=n?S.Slot:"div",{videoRef:u}=g(),{isLoading:o}=lt(u);return(0,C.jsx)(e,{...r,style:{...r.style,pointerEvents:"none"},"data-loading":o,children:t})}),Ot=({...t})=>{let{videoRef:n}=g(),r=(0,V.useRef)(null);return V.default.useEffect(()=>{let e=n==null?void 0:n.current;if(r.current&&e){let u=0,o=!1,s=null,c=()=>{s&&clearInterval(s),s=setInterval(()=>{u=e.currentTime,r.current&&(r.current.currentTime=u)},100)},y=()=>{s&&(clearInterval(s),s=null)},a=()=>{o=!0,c()},b=()=>{o=!1,y()};return e.addEventListener("play",a),e.addEventListener("pause",b),()=>{y(),e.removeEventListener("play",a),e.removeEventListener("pause",b)}}},[n==null?void 0:n.current]),n!=null&&n.current?(0,C.jsx)("div",{...t,style:{...t.style,position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none"},children:(0,C.jsx)("video",{ref:r,src:n.current.src,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"cover"}})}):null};0&&(module.exports={Controls,Download,ExitFullscreen,Fullscreen,Loading,Mute,Pause,PictureInPicture,Play,SeekBackward,SeekForward,Shadow,Speed,Unmute,Video,VideoProvider,useVideo});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/wrapper.tsx","../src/video.tsx","../src/hooks/use-autoplay-by-force.tsx","../src/hooks/use-hot-keys.tsx","../src/hooks/use-seek.tsx","../src/hooks/use-play-pause.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/keyboard.tsx","../src/hooks/use-autoplay-on-visible.tsx","../src/hooks/use-get-duration.tsx","../src/hooks/use-speed.tsx","../src/hooks/use-start-at.tsx","../src/hooks/use-current-time.tsx","../src/hooks/use-video-state.tsx","../src/hooks/use-volume.tsx","../src/hooks/use-buffer.tsx","../src/hooks/use-download.tsx","../src/hooks/use-range.tsx","../src/components.tsx","../src/hooks/use-loading.tsx"],"sourcesContent":["\"use client\";\n\nexport { VideoProvider, useVideo } from \"./wrapper\";\nexport { Video } from \"./video\";\nexport * from \"./components\";\nexport * from \"./types\";\n","import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, {\n forwardRef,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\nimport { useAutoplayOnVisible } from \"./hooks\";\n\ninterface Props\n extends Omit<React.ComponentProps<\"video\">, \"autoPlay\" | \"preload\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n muteFallback?: (onMute: () => void) => React.ReactNode;\n autoPlayOnVisible?: boolean | number;\n ranges?: number[];\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n (\n {\n src,\n autoPlay,\n muteFallback,\n controls,\n preload = \"metadata\",\n autoPlayOnVisible,\n ranges,\n ...props\n },\n ref\n ) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n const isAdjustingRef = useRef(false);\n const rafIdRef = useRef<number | null>(null);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Validate ranges: ensure they're valid and start < end\n const isValidRange =\n ranges &&\n ranges.length >= 2 &&\n typeof ranges[0] === \"number\" &&\n typeof ranges[1] === \"number\" &&\n ranges[0] >= 0 &&\n ranges[1] > ranges[0] &&\n isFinite(ranges[0]) &&\n isFinite(ranges[1]);\n\n // Safely get range values (only use when isValidRange is true)\n const rangeStart = isValidRange ? ranges[0] : undefined;\n const rangeEnd = isValidRange ? ranges[1] : undefined;\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n\n // Safari: Reset adjustment flags when src changes to prevent stale state\n return () => {\n isAdjustingRef.current = false;\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, [src, ref, setVideoRef]);\n\n // Cleanup requestAnimationFrame and setTimeout on unmount (critical for Safari)\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, []);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n useAutoplayOnVisible(\n videoRef,\n typeof autoPlayOnVisible === \"number\"\n ? autoPlayOnVisible\n : !autoPlayOnVisible\n ? 0.5\n : undefined,\n !!autoPlayOnVisible\n );\n\n const onPlay = useCallback(() => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n }, [videoRef]);\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n preload={preload}\n playsInline\n onCanPlay={(e) => {\n // Set initial position when video is ready to play (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n // Only adjust if we're outside the range to avoid unnecessary seeks\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n video.currentTime = rangeStart;\n }\n }\n props.onCanPlay?.(e);\n }}\n onSeeked={(e) => {\n // Adjust position after user seeks (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n // Only seek if significantly outside range to avoid infinite loop\n if (Math.abs(currentTime - rangeStart) > 0.01) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay in case onSeeked doesn't fire again\n // Cleanup existing RAF before setting new one (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n return; // Exit early to prevent calling props.onSeeked twice\n }\n }\n }\n isAdjustingRef.current = false;\n props.onSeeked?.(e);\n }}\n onTimeUpdate={(e) => {\n const video = e.currentTarget;\n\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n !isAdjustingRef.current\n ) {\n const currentTime = video.currentTime;\n\n // During playback: loop back when reaching or exceeding the end boundary\n if (!video.paused && currentTime >= rangeEnd) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after seek completes (onSeeked will handle this)\n // But add a fallback timeout in case onSeeked doesn't fire\n // Cleanup existing timeout before setting new one (Safari memory safety)\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n timeoutIdRef.current = setTimeout(() => {\n if (isAdjustingRef.current) {\n isAdjustingRef.current = false;\n }\n timeoutIdRef.current = null;\n }, 100);\n rafIdRef.current = null;\n });\n }\n // When paused: ensure we're within range\n else if (\n video.paused &&\n (currentTime < rangeStart || currentTime > rangeEnd)\n ) {\n // Only adjust if significantly outside range to avoid constant micro-adjustments\n if (\n Math.abs(currentTime - rangeStart) > 0.01 ||\n currentTime > rangeEnd\n ) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay since we're paused\n // Cleanup existing RAF and timeout before setting new ones (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n }\n }\n }\n\n props.onTimeUpdate?.(e);\n }}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayByForce = (\n videoRef: VideoRef,\n enabled: boolean,\n setError?: (error: string | null) => void\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const playVideo = async () => {\n try {\n await videoRef.current?.play();\n } catch (error) {\n // If autoplay fails, try muting and playing again\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n setError?.(\"NotAllowedError\");\n console.error(\"NotAllowedError\");\n if (videoRef?.current) {\n videoRef.current.muted = true;\n try {\n await videoRef.current.play();\n } catch (retryError) {\n console.error(retryError);\n }\n }\n } else {\n console.error(error);\n }\n }\n };\n\n playVideo();\n }, [enabled, videoRef?.current]);\n};\n","import { useEffect } from \"react\";\n\nexport const useHotKeys = (\n key: string,\n func: (event: KeyboardEvent) => void,\n enabled = true\n) => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === key) {\n event.preventDefault();\n func(event);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [key, func, enabled]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSeek = (videoRef: VideoRef, value = 10) => {\n const seekForward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime += value;\n }\n }, [videoRef?.current]);\n\n const seekBackward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime -= value;\n }\n }, [videoRef?.current]);\n\n return { seekForward, seekBackward };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (videoRef: VideoRef) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.paused\n ? videoRef.current.play()\n : videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n const play = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.play();\n }\n }, [videoRef?.current]);\n\n const pause = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!videoRef?.current.paused);\n\n if (videoRef?.current) {\n videoRef.current.addEventListener(\"play\", handlePlay);\n videoRef.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", handlePlay);\n videoRef.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n return { togglePlay, isPlaying, play, pause };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (videoRef: VideoRef) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, [videoRef?.current]);\n\n const mute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = true;\n }\n }, [videoRef?.current]);\n\n const unmute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = false;\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef?.current]);\n\n return { toggleMute, isMuted, mute, unmute };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nconst useFullscreen = (videoRef: VideoRef) => {\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const previousStylesRef = React.useRef<{\n objectFit: string;\n borderRadius: string;\n width: string;\n height: string;\n maxWidth: string;\n maxHeight: string;\n margin: string;\n } | null>(null);\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n const isCurrentlyFullscreen = !!document.fullscreenElement;\n setIsFullscreen(isCurrentlyFullscreen);\n\n // Apply styles based on fullscreen state\n const video = videoRef?.current;\n if (video) {\n if (isCurrentlyFullscreen) {\n // Store previous styles before entering fullscreen\n previousStylesRef.current = {\n objectFit: video.style.objectFit || \"cover\",\n borderRadius: video.style.borderRadius || \"\",\n width: video.style.width || \"\",\n height: video.style.height || \"\",\n maxWidth: video.style.maxWidth || \"\",\n maxHeight: video.style.maxHeight || \"\",\n margin: video.style.margin || \"\",\n };\n // Apply fullscreen styles\n video.style.objectFit = \"contain\";\n video.style.borderRadius = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.maxWidth = \"none\";\n video.style.maxHeight = \"none\";\n video.style.margin = \"0\";\n } else {\n // Restore previous styles when exiting fullscreen\n if (previousStylesRef.current) {\n video.style.objectFit = previousStylesRef.current.objectFit;\n video.style.borderRadius = previousStylesRef.current.borderRadius;\n video.style.width = previousStylesRef.current.width;\n video.style.height = previousStylesRef.current.height;\n video.style.maxWidth = previousStylesRef.current.maxWidth;\n video.style.maxHeight = previousStylesRef.current.maxHeight;\n video.style.margin = previousStylesRef.current.margin;\n previousStylesRef.current = null;\n }\n }\n }\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [videoRef]);\n\n const toggleFullscreen = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = video?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n } else {\n document.exitFullscreen();\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n\nexport { useFullscreen };\n","import type { VideoRef } from \"../types\";\n\nexport const usePictureInPicture = (videoRef: VideoRef) => {\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n const requestPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await video.requestPictureInPicture();\n };\n\n const exitPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await document.exitPictureInPicture();\n };\n\n return {\n togglePictureInPicture,\n requestPictureInPicture,\n exitPictureInPicture,\n };\n};\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayOnVisible = (\n videoRef: VideoRef,\n threshold: number | undefined,\n enabled = true\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (!videoRef?.current) return;\n\n if (entry.isIntersecting) {\n videoRef.current.play().catch((error) => {\n if (!videoRef.current) return;\n\n videoRef.current.pause();\n videoRef.current.muted = true;\n videoRef.current.play();\n console.error(error);\n });\n } else {\n videoRef.current?.pause();\n }\n });\n },\n { threshold: threshold ?? 0.5 }\n );\n\n observer.observe(videoRef?.current);\n\n return () => {\n observer.disconnect();\n };\n }, [videoRef?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useGetDuration = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n const [duration, setDuration] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n setIsLoading(true);\n\n const getDuration = () => {\n setDuration(videoRef.current?.duration ?? null);\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const video = videoRef.current;\n\n // Check if duration is already available\n if (video.duration && !isNaN(video.duration)) {\n setDuration(video.duration);\n setIsLoading(false);\n } else {\n // Add event listeners\n video.addEventListener(\"loadedmetadata\", getDuration);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"loadeddata\", getDuration);\n\n return () => {\n video.removeEventListener(\"loadedmetadata\", getDuration);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"loadeddata\", getDuration);\n };\n }\n }, [videoRef]);\n\n return { duration, isLoading };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSpeed = (videoRef: VideoRef) => {\n const [speed, setSpeed] = React.useState(1);\n\n const onChangeSpeed = (speed: number) => {\n setSpeed(speed);\n };\n\n // Get the speed from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setSpeed(videoRef.current.playbackRate);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.playbackRate = speed;\n }, [speed, videoRef?.current]);\n\n return { speed, onChangeSpeed };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useStartAt = (videoRef: VideoRef, startAt: number) => {\n React.useEffect(() => {\n if (!videoRef?.current || !startAt) return;\n\n const video = videoRef?.current;\n if (video && startAt) {\n video.currentTime = startAt;\n }\n }, [startAt, videoRef?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types.js\";\n\nexport const useCurrentTime = (videoRef: VideoRef, interval = 10) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n setCurrentTime(videoRef.current?.currentTime || 0);\n }, interval);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n // Store handlers in variables for proper cleanup (critical for Safari memory safety)\n const handlePlay = () => setIsPlaying(true);\n const handlePause = () => setIsPlaying(false);\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }, [videoRef?.current]);\n\n const onTimeUpdate = (time: number) => {\n if (videoRef?.current) {\n setCurrentTime(time);\n videoRef.current.currentTime = time;\n }\n };\n\n return {\n currentTime,\n onTimeUpdate,\n };\n};\n","import { RefObject, useEffect, useState } from \"react\";\n\nconst useVideoState = (videoRef: RefObject<HTMLVideoElement | null>) => {\n const [isPlaying, setIsPlaying] = useState(false);\n const [isMuted, setIsMuted] = useState(false);\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n useEffect(() => {\n const video = videoRef.current;\n\n if (video) {\n video.addEventListener(\"play\", () => setIsPlaying(true));\n video.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n video.removeEventListener(\"play\", () => setIsPlaying(true));\n video.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }\n }, [videoRef]);\n\n useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef]);\n\n useEffect(() => {\n if (!videoRef?.current) return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [videoRef]);\n\n return { isPlaying, isMuted, isFullscreen };\n};\n\nexport { useVideoState };\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useVolume = (videoRef: VideoRef, initialVolume = 100) => {\n const [volume, setVolume] = React.useState(initialVolume);\n\n const onChangeVolume = (volume: number) => {\n setVolume(volume);\n };\n\n // Get the volume from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setVolume(videoRef.current.volume * 100);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.volume = volume / 100;\n }, [volume, videoRef?.current]);\n\n return { volume, onChangeVolume };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types.js\";\n\nexport const useBuffer = (videoRef: VideoRef, duration?: number) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [buffered, setBuffered] = React.useState(0);\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n if (videoRef.current?.buffered.length) {\n setBuffered(\n videoRef.current.buffered.end(videoRef.current.buffered.length - 1)\n );\n }\n }, 10);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.addEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current?.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }, []);\n\n return {\n buffered,\n bufferedPercentage: (buffered / (duration || 0)) * 100 || 0,\n };\n};\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useDownload = (videoRef: VideoRef) => {\n const [isDownloading, setIsDownloading] = useState(false);\n const [downloadProgress, setDownloadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const downloadVideo = useCallback(\n async (filename?: string) => {\n if (!videoRef?.current) {\n setError(\"Video element not found\");\n return;\n }\n\n const video = videoRef.current;\n const videoSrc = video.src || video.currentSrc;\n\n if (!videoSrc) {\n setError(\"No video source found\");\n return;\n }\n\n try {\n setIsDownloading(true);\n setError(null);\n setDownloadProgress(0);\n\n // Fetch the video file\n const response = await fetch(videoSrc);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch video: ${response.statusText}`);\n }\n\n // Get the content length for progress tracking\n const contentLength = response.headers.get(\"content-length\");\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n // Create a readable stream to track progress\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Failed to create download stream\");\n }\n\n const chunks: BlobPart[] = [];\n let receivedLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n chunks.push(value);\n receivedLength += value.length;\n\n if (total > 0) {\n const progress = (receivedLength / total) * 100;\n setDownloadProgress(Math.round(progress));\n }\n }\n\n // Combine chunks into a single blob\n const blob = new Blob(chunks, {\n type: response.headers.get(\"content-type\") || \"video/mp4\",\n });\n\n // Create download link\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n\n // Generate filename if not provided\n const defaultFilename = filename || `video-${Date.now()}.mp4`;\n link.download = defaultFilename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up\n URL.revokeObjectURL(url);\n\n setDownloadProgress(100);\n setIsDownloading(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Download failed\");\n setIsDownloading(false);\n setDownloadProgress(0);\n }\n },\n [videoRef]\n );\n\n // Alternative simple download method for direct video URLs\n const downloadDirect = useCallback(\n (filename?: string) => {\n if (!videoRef?.current) {\n setError(\"Video element not found\");\n return;\n }\n\n const video = videoRef.current;\n const videoSrc = video.src || video.currentSrc;\n\n if (!videoSrc) {\n setError(\"No video source found\");\n return;\n }\n\n try {\n setIsDownloading(true);\n setError(null);\n setDownloadProgress(0);\n\n const link = document.createElement(\"a\");\n link.href = videoSrc;\n link.download = filename || `video-${Date.now()}.mp4`;\n link.target = \"_blank\";\n\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n setIsDownloading(false);\n setDownloadProgress(100);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Download failed\");\n setIsDownloading(false);\n setDownloadProgress(0);\n }\n },\n [videoRef]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n setIsDownloading(false);\n setDownloadProgress(0);\n setError(null);\n };\n }, []);\n\n return {\n downloadVideo,\n downloadDirect,\n isDownloading,\n downloadProgress,\n error,\n resetError: () => setError(null),\n };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useRange = (videoRef: VideoRef, range: [number, number]) => {\n React.useEffect(() => {\n if (!videoRef?.current || !range) return;\n\n const video = videoRef.current;\n\n if (video) {\n const handleTimeUpdate = () => {\n if (video.currentTime >= range[1]) {\n video.currentTime = range[0];\n } else if (video.currentTime <= range[0]) {\n video.currentTime = range[0];\n }\n };\n\n video.addEventListener(\"timeupdate\", handleTimeUpdate);\n\n return () => {\n video.removeEventListener(\"timeupdate\", handleTimeUpdate);\n };\n }\n }, [range, videoRef?.current]);\n};\n","import React, { RefObject, useRef } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useCurrentTime } from \"./hooks/use-current-time\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useDownload } from \"./hooks/use-download\";\nimport { useSpeed } from \"./hooks\";\nimport { useLoading } from \"./hooks/use-loading\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\ninterface SpeedProps extends Props {\n value: number;\n onClick?: () => void;\n}\n\nconst Speed = React.memo(\n ({ children, asChild, value, onClick, ...props }: SpeedProps) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { speed, onChangeSpeed } = useSpeed(\n videoRef as RefObject<HTMLVideoElement>\n );\n\n return (\n <Element\n {...props}\n value={value}\n onClick={() => {\n onChangeSpeed(value);\n onClick?.();\n }}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst PictureInPicture = React.memo(\n ({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n return (\n <Element {...props} onClick={togglePictureInPicture}>\n {children}\n </Element>\n );\n }\n);\n\nconst Download = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { downloadDirect } = useDownload(videoRef);\n\n return (\n <Element {...props} onClick={() => downloadDirect()}>\n {children}\n </Element>\n );\n});\n\ninterface LoadingProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Loading = React.memo(({ children, asChild, ...props }: LoadingProps) => {\n const Element = asChild ? Slot : \"div\";\n const { videoRef } = useVideo();\n\n const { isLoading } = useLoading(videoRef);\n\n return (\n <Element\n {...props}\n style={{ ...props.style, pointerEvents: \"none\" }}\n data-loading={isLoading}\n >\n {children}\n </Element>\n );\n});\n\ninterface ShadowProps extends React.ComponentProps<\"div\"> {}\n\nconst Shadow = ({ ...props }: ShadowProps) => {\n const { videoRef } = useVideo();\n\n const shadowVideoRef = useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n const video = videoRef?.current;\n if (shadowVideoRef.current && video) {\n let currentTime = 0;\n let isPlaying = false;\n let interval: ReturnType<typeof setInterval> | null = null;\n\n const startInterval = () => {\n if (interval) clearInterval(interval);\n interval = setInterval(() => {\n currentTime = video.currentTime;\n if (shadowVideoRef.current) {\n shadowVideoRef.current.currentTime = currentTime;\n }\n }, 100);\n };\n\n const stopInterval = () => {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n };\n\n const handlePlay = () => {\n isPlaying = true;\n startInterval();\n };\n\n const handlePause = () => {\n isPlaying = false;\n stopInterval();\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n stopInterval();\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n if (!videoRef?.current) return null;\n\n return (\n <div\n {...props}\n style={{\n ...props.style,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <video\n ref={shadowVideoRef}\n src={videoRef.current.src}\n muted\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n }}\n />\n </div>\n );\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n Speed,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n PictureInPicture,\n Download,\n Loading,\n Shadow,\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useLoading = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n const handleLoadStart = () => {\n setIsLoading(true);\n };\n\n const handleLoadedMetadata = () => {\n // Metadata loaded but video might not be ready to play yet\n // Keep loading true until canplay\n };\n\n const handleLoadedData = () => {\n // First frame loaded, but might still be buffering\n // Keep loading true until canplay\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n };\n\n const handleWaiting = () => {\n // Video is waiting for data (buffering)\n setIsLoading(true);\n };\n\n const handlePlaying = () => {\n // Video is playing, so it's not loading anymore\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const handleAbort = () => {\n setIsLoading(false);\n };\n\n const handleSuspend = () => {\n // Loading suspended (e.g., user paused)\n // Don't change loading state here\n };\n\n // Add event listeners\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"abort\", handleAbort);\n video.addEventListener(\"suspend\", handleSuspend);\n\n // Check initial state\n if (video.readyState >= 2) {\n setIsLoading(false);\n }\n\n return () => {\n // Remove event listeners\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"abort\", handleAbort);\n video.removeEventListener(\"suspend\", handleSuspend);\n };\n }, [videoRef]);\n\n return { isLoading };\n};\n"],"mappings":"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","names":["index_exports","__export","Controls","Download","ExitFullscreen","Fullscreen","Loading","Mute","Pause","PictureInPicture","Play","SeekBackward","SeekForward","Shadow","Speed","Unmute","Video","VideoProvider","useVideo","__toCommonJS","import_react","import_jsx_runtime","VideoContext","VideoProvider","React","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","import_react","import_react","useAutoplayByForce","videoRef","enabled","setError","React","_a","error","retryError","import_react","useHotKeys","key","func","enabled","handleKeyDown","event","import_react","useSeek","videoRef","value","seekForward","React","seekBackward","import_react","usePlayPause","videoRef","isPlaying","setIsPlaying","React","togglePlay","play","pause","handlePlay","handlePause","_a","_b","import_react","useMuteUnmute","videoRef","isMuted","setIsMuted","React","toggleMute","mute","unmute","handleVolumeChange","_a","import_react","useFullscreen","videoRef","isFullscreen","setIsFullscreen","React","previousStylesRef","handleFullscreenChange","isCurrentlyFullscreen","video","toggleFullscreen","isSafari","videoContainer","usePictureInPicture","videoRef","video","error","videoContainer","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","import_react","useAutoplayOnVisible","videoRef","threshold","enabled","React","observer","entries","entry","_a","error","import_react","import_react","useSpeed","videoRef","speed","setSpeed","React","onChangeSpeed","import_react","import_react","import_react","import_react","import_react","import_react","useDownload","videoRef","isDownloading","setIsDownloading","downloadProgress","setDownloadProgress","error","setError","downloadVideo","filename","_a","video","videoSrc","response","contentLength","total","reader","chunks","receivedLength","done","value","progress","blob","url","link","defaultFilename","err","downloadDirect","import_react","import_jsx_runtime","Video","src","autoPlay","muteFallback","controls","preload","autoPlayOnVisible","ranges","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","isAdjustingRef","rafIdRef","timeoutIdRef","isValidRange","rangeStart","rangeEnd","video","thirdPartyRef","useAutoplayByForce","useAutoplayOnVisible","onPlay","_a","_b","_c","e","currentTime","Keyboards","import_react","import_react_slot","import_react","useLoading","videoRef","isLoading","setIsLoading","React","video","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handleError","handleAbort","handleSuspend","import_jsx_runtime","Controls","React","children","asChild","props","Play","Element","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","Speed","value","onClick","speed","onChangeSpeed","useSpeed","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","PictureInPicture","togglePictureInPicture","usePictureInPicture","Download","downloadDirect","useDownload","Loading","isLoading","useLoading","Shadow","shadowVideoRef","video","currentTime","isPlaying","interval","startInterval","stopInterval","handlePlay","handlePause"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/wrapper.tsx","../src/video.tsx","../src/hooks/use-autoplay-by-force.tsx","../src/hooks/use-hot-keys.tsx","../src/hooks/use-seek.tsx","../src/hooks/use-play-pause.tsx","../src/hooks/use-mute-unmute.tsx","../src/hooks/use-fullscreen.tsx","../src/hooks/use-picture-in-picture.tsx","../src/keyboard.tsx","../src/hooks/use-autoplay-on-visible.tsx","../src/hooks/use-get-duration.tsx","../src/hooks/use-speed.tsx","../src/hooks/use-start-at.tsx","../src/hooks/use-current-time.tsx","../src/hooks/use-video-state.tsx","../src/hooks/use-volume.tsx","../src/hooks/use-buffer.tsx","../src/hooks/use-download.tsx","../src/hooks/use-range.tsx","../src/components.tsx","../src/hooks/use-loading.tsx"],"sourcesContent":["\"use client\";\n\nexport { VideoProvider, useVideo } from \"./wrapper\";\nexport { Video } from \"./video\";\nexport * from \"./components\";\nexport * from \"./types\";\n","import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, {\n forwardRef,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\nimport { useAutoplayOnVisible } from \"./hooks\";\n\ninterface Props\n extends Omit<React.ComponentProps<\"video\">, \"autoPlay\" | \"preload\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n muteFallback?: (onMute: () => void) => React.ReactNode;\n autoPlayOnVisible?: boolean | number;\n ranges?: number[];\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n (\n {\n src,\n autoPlay,\n muteFallback,\n controls,\n preload = \"metadata\",\n autoPlayOnVisible,\n ranges,\n ...props\n },\n ref\n ) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n const isAdjustingRef = useRef(false);\n const rafIdRef = useRef<number | null>(null);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Validate ranges: ensure they're valid and start < end\n const isValidRange =\n ranges &&\n ranges.length >= 2 &&\n typeof ranges[0] === \"number\" &&\n typeof ranges[1] === \"number\" &&\n ranges[0] >= 0 &&\n ranges[1] > ranges[0] &&\n isFinite(ranges[0]) &&\n isFinite(ranges[1]);\n\n // Safely get range values (only use when isValidRange is true)\n const rangeStart = isValidRange ? ranges[0] : undefined;\n const rangeEnd = isValidRange ? ranges[1] : undefined;\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n\n // Safari: Reset adjustment flags when src changes to prevent stale state\n return () => {\n isAdjustingRef.current = false;\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, [src, ref, setVideoRef]);\n\n // Cleanup requestAnimationFrame and setTimeout on unmount (critical for Safari)\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, []);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n useAutoplayOnVisible(\n videoRef,\n typeof autoPlayOnVisible === \"number\"\n ? autoPlayOnVisible\n : !autoPlayOnVisible\n ? 0.5\n : undefined,\n !!autoPlayOnVisible\n );\n\n const onPlay = useCallback(() => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n }, [videoRef]);\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n preload={preload}\n playsInline\n onLoadedMetadata={(e) => {\n // Set initial position as early as possible when metadata loads\n // This ensures video starts at rangeStart even with autoplay\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined\n ) {\n // Always set to rangeStart on initial load to ensure correct starting position\n video.currentTime = rangeStart;\n }\n props.onLoadedMetadata?.(e);\n }}\n onCanPlay={(e) => {\n // Ensure position is correct when video is ready to play\n // This is a backup in case onLoadedMetadata didn't set it correctly\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined\n ) {\n const currentTime = video.currentTime;\n // Only adjust if significantly outside range to avoid unnecessary seeks\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n video.currentTime = rangeStart;\n }\n }\n props.onCanPlay?.(e);\n }}\n onSeeked={(e) => {\n // Adjust position after user seeks (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n // Only seek if significantly outside range to avoid infinite loop\n if (Math.abs(currentTime - rangeStart) > 0.01) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay in case onSeeked doesn't fire again\n // Cleanup existing RAF before setting new one (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n return; // Exit early to prevent calling props.onSeeked twice\n }\n }\n }\n isAdjustingRef.current = false;\n props.onSeeked?.(e);\n }}\n onTimeUpdate={(e) => {\n const video = e.currentTarget;\n\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n !isAdjustingRef.current\n ) {\n const currentTime = video.currentTime;\n\n // During playback: loop back when reaching or exceeding the end boundary\n if (!video.paused && currentTime >= rangeEnd) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after seek completes (onSeeked will handle this)\n // But add a fallback timeout in case onSeeked doesn't fire\n // Cleanup existing timeout before setting new one (Safari memory safety)\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n timeoutIdRef.current = setTimeout(() => {\n if (isAdjustingRef.current) {\n isAdjustingRef.current = false;\n }\n timeoutIdRef.current = null;\n }, 100);\n rafIdRef.current = null;\n });\n }\n // When paused: ensure we're within range\n else if (\n video.paused &&\n (currentTime < rangeStart || currentTime > rangeEnd)\n ) {\n // Only adjust if significantly outside range to avoid constant micro-adjustments\n if (\n Math.abs(currentTime - rangeStart) > 0.01 ||\n currentTime > rangeEnd\n ) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay since we're paused\n // Cleanup existing RAF and timeout before setting new ones (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n }\n }\n }\n\n props.onTimeUpdate?.(e);\n }}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayByForce = (\n videoRef: VideoRef,\n enabled: boolean,\n setError?: (error: string | null) => void\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const playVideo = async () => {\n try {\n await videoRef.current?.play();\n } catch (error) {\n // If autoplay fails, try muting and playing again\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n setError?.(\"NotAllowedError\");\n console.error(\"NotAllowedError\");\n if (videoRef?.current) {\n videoRef.current.muted = true;\n try {\n await videoRef.current.play();\n } catch (retryError) {\n console.error(retryError);\n }\n }\n } else {\n console.error(error);\n }\n }\n };\n\n playVideo();\n }, [enabled, videoRef?.current]);\n};\n","import { useEffect } from \"react\";\n\nexport const useHotKeys = (\n key: string,\n func: (event: KeyboardEvent) => void,\n enabled = true\n) => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === key) {\n event.preventDefault();\n func(event);\n }\n };\n\n useEffect(() => {\n if (!enabled) return;\n\n document.addEventListener(\"keydown\", handleKeyDown);\n\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [key, func, enabled]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSeek = (videoRef: VideoRef, value = 10) => {\n const seekForward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime += value;\n }\n }, [videoRef?.current]);\n\n const seekBackward = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.currentTime -= value;\n }\n }, [videoRef?.current]);\n\n return { seekForward, seekBackward };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const usePlayPause = (videoRef: VideoRef) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n\n const togglePlay = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.paused\n ? videoRef.current.play()\n : videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n const play = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.play();\n }\n }, [videoRef?.current]);\n\n const pause = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.pause();\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const handlePlay = () => {\n setIsPlaying(true);\n };\n const handlePause = () => {\n setIsPlaying(false);\n };\n\n setIsPlaying(!videoRef?.current.paused);\n\n if (videoRef?.current) {\n videoRef.current.addEventListener(\"play\", handlePlay);\n videoRef.current.addEventListener(\"pause\", handlePause);\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", handlePlay);\n videoRef.current?.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n return { togglePlay, isPlaying, play, pause };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useMuteUnmute = (videoRef: VideoRef) => {\n const [isMuted, setIsMuted] = React.useState(false);\n\n const toggleMute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n }, [videoRef?.current]);\n\n const mute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = true;\n }\n }, [videoRef?.current]);\n\n const unmute = React.useCallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = false;\n }\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef?.current]);\n\n return { toggleMute, isMuted, mute, unmute };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nconst useFullscreen = (videoRef: VideoRef) => {\n const [isFullscreen, setIsFullscreen] = React.useState(false);\n const previousStylesRef = React.useRef<{\n objectFit: string;\n borderRadius: string;\n width: string;\n height: string;\n maxWidth: string;\n maxHeight: string;\n margin: string;\n } | null>(null);\n\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n const isCurrentlyFullscreen = !!document.fullscreenElement;\n setIsFullscreen(isCurrentlyFullscreen);\n\n // Apply styles based on fullscreen state\n const video = videoRef?.current;\n if (video) {\n if (isCurrentlyFullscreen) {\n // Store previous styles before entering fullscreen\n previousStylesRef.current = {\n objectFit: video.style.objectFit || \"cover\",\n borderRadius: video.style.borderRadius || \"\",\n width: video.style.width || \"\",\n height: video.style.height || \"\",\n maxWidth: video.style.maxWidth || \"\",\n maxHeight: video.style.maxHeight || \"\",\n margin: video.style.margin || \"\",\n };\n // Apply fullscreen styles\n video.style.objectFit = \"contain\";\n video.style.borderRadius = \"0\";\n video.style.width = \"100%\";\n video.style.height = \"100%\";\n video.style.maxWidth = \"none\";\n video.style.maxHeight = \"none\";\n video.style.margin = \"0\";\n } else {\n // Restore previous styles when exiting fullscreen\n if (previousStylesRef.current) {\n video.style.objectFit = previousStylesRef.current.objectFit;\n video.style.borderRadius = previousStylesRef.current.borderRadius;\n video.style.width = previousStylesRef.current.width;\n video.style.height = previousStylesRef.current.height;\n video.style.maxWidth = previousStylesRef.current.maxWidth;\n video.style.maxHeight = previousStylesRef.current.maxHeight;\n video.style.margin = previousStylesRef.current.margin;\n previousStylesRef.current = null;\n }\n }\n }\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [videoRef]);\n\n const toggleFullscreen = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const video = videoRef?.current;\n\n if (video && isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n return;\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n return;\n }\n }\n\n const videoContainer = video?.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n\n if (videoContainer) {\n if (!isFullscreen) {\n videoContainer.requestFullscreen();\n } else {\n document.exitFullscreen();\n }\n }\n };\n\n return { isFullscreen: isFullscreen ?? false, toggleFullscreen };\n};\n\nexport { useFullscreen };\n","import type { VideoRef } from \"../types\";\n\nexport const usePictureInPicture = (videoRef: VideoRef) => {\n const togglePictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n\n try {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture();\n } else {\n await video.requestPictureInPicture();\n }\n } catch (error) {\n // Fallback for browsers that don't support PiP\n const isSafari = /^((?!chrome|android).)*safari/i.test(\n navigator.userAgent\n );\n\n if (isSafari) {\n if ((video as any).webkitEnterFullscreen) {\n (video as any).webkitEnterFullscreen();\n } else if (video.requestFullscreen) {\n video.requestFullscreen();\n }\n } else {\n const videoContainer = video.closest(\n \"[data-zuude-video-wrapper]\"\n ) as HTMLElement;\n if (videoContainer) {\n if (!document.fullscreenElement) {\n await videoContainer.requestFullscreen();\n } else {\n await document.exitFullscreen();\n }\n }\n }\n }\n };\n\n const requestPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await video.requestPictureInPicture();\n };\n\n const exitPictureInPicture = async () => {\n const video = videoRef?.current;\n if (!video) return;\n await document.exitPictureInPicture();\n };\n\n return {\n togglePictureInPicture,\n requestPictureInPicture,\n exitPictureInPicture,\n };\n};\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useAutoplayOnVisible = (\n videoRef: VideoRef,\n threshold: number | undefined,\n enabled = true\n) => {\n React.useEffect(() => {\n if (!videoRef?.current || !enabled) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n if (!videoRef?.current) return;\n\n if (entry.isIntersecting) {\n videoRef.current.play().catch((error) => {\n if (!videoRef.current) return;\n\n videoRef.current.pause();\n videoRef.current.muted = true;\n videoRef.current.play();\n console.error(error);\n });\n } else {\n videoRef.current?.pause();\n }\n });\n },\n { threshold: threshold ?? 0.5 }\n );\n\n observer.observe(videoRef?.current);\n\n return () => {\n observer.disconnect();\n };\n }, [videoRef?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useGetDuration = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n const [duration, setDuration] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n setIsLoading(true);\n\n const getDuration = () => {\n setDuration(videoRef.current?.duration ?? null);\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const video = videoRef.current;\n\n // Check if duration is already available\n if (video.duration && !isNaN(video.duration)) {\n setDuration(video.duration);\n setIsLoading(false);\n } else {\n // Add event listeners\n video.addEventListener(\"loadedmetadata\", getDuration);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"loadeddata\", getDuration);\n\n return () => {\n video.removeEventListener(\"loadedmetadata\", getDuration);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"loadeddata\", getDuration);\n };\n }\n }, [videoRef]);\n\n return { duration, isLoading };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useSpeed = (videoRef: VideoRef) => {\n const [speed, setSpeed] = React.useState(1);\n\n const onChangeSpeed = (speed: number) => {\n setSpeed(speed);\n };\n\n // Get the speed from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setSpeed(videoRef.current.playbackRate);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.playbackRate = speed;\n }, [speed, videoRef?.current]);\n\n return { speed, onChangeSpeed };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useStartAt = (videoRef: VideoRef, startAt: number) => {\n React.useEffect(() => {\n if (!videoRef?.current || !startAt) return;\n\n const video = videoRef?.current;\n if (video && startAt) {\n video.currentTime = startAt;\n }\n }, [startAt, videoRef?.current]);\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types.js\";\n\nexport const useCurrentTime = (videoRef: VideoRef, interval = 10) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [currentTime, setCurrentTime] = React.useState(0);\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n setCurrentTime(videoRef.current?.currentTime || 0);\n }, interval);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n // Store handlers in variables for proper cleanup (critical for Safari memory safety)\n const handlePlay = () => setIsPlaying(true);\n const handlePause = () => setIsPlaying(false);\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }, [videoRef?.current]);\n\n const onTimeUpdate = (time: number) => {\n if (videoRef?.current) {\n setCurrentTime(time);\n videoRef.current.currentTime = time;\n }\n };\n\n return {\n currentTime,\n onTimeUpdate,\n };\n};\n","import { RefObject, useEffect, useState } from \"react\";\n\nconst useVideoState = (videoRef: RefObject<HTMLVideoElement | null>) => {\n const [isPlaying, setIsPlaying] = useState(false);\n const [isMuted, setIsMuted] = useState(false);\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n useEffect(() => {\n const video = videoRef.current;\n\n if (video) {\n video.addEventListener(\"play\", () => setIsPlaying(true));\n video.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n video.removeEventListener(\"play\", () => setIsPlaying(true));\n video.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }\n }, [videoRef]);\n\n useEffect(() => {\n if (!videoRef?.current) return;\n\n // Set the initial state\n setIsMuted(videoRef.current.muted);\n\n const handleVolumeChange = () => {\n if (videoRef.current) {\n setIsMuted(videoRef.current.muted);\n }\n };\n\n videoRef.current.addEventListener(\"volumechange\", handleVolumeChange);\n\n return () => {\n videoRef.current?.removeEventListener(\"volumechange\", handleVolumeChange);\n };\n }, [videoRef]);\n\n useEffect(() => {\n if (!videoRef?.current) return;\n\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n return () =>\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n }, [videoRef]);\n\n return { isPlaying, isMuted, isFullscreen };\n};\n\nexport { useVideoState };\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useVolume = (videoRef: VideoRef, initialVolume = 100) => {\n const [volume, setVolume] = React.useState(initialVolume);\n\n const onChangeVolume = (volume: number) => {\n setVolume(volume);\n };\n\n // Get the volume from the video element\n React.useEffect(() => {\n if (!videoRef?.current) return;\n setVolume(videoRef.current.volume * 100);\n }, [videoRef?.current]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.volume = volume / 100;\n }, [volume, videoRef?.current]);\n\n return { volume, onChangeVolume };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types.js\";\n\nexport const useBuffer = (videoRef: VideoRef, duration?: number) => {\n const [isPlaying, setIsPlaying] = React.useState(false);\n const [buffered, setBuffered] = React.useState(0);\n\n React.useEffect(() => {\n if (videoRef?.current && isPlaying) {\n const intervalId = setInterval(() => {\n if (videoRef.current?.buffered.length) {\n setBuffered(\n videoRef.current.buffered.end(videoRef.current.buffered.length - 1)\n );\n }\n }, 10);\n\n return () => clearInterval(intervalId);\n }\n }, [videoRef?.current, isPlaying]);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n videoRef.current.addEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current.addEventListener(\"pause\", () => setIsPlaying(false));\n\n return () => {\n videoRef.current?.removeEventListener(\"play\", () => setIsPlaying(true));\n videoRef.current?.removeEventListener(\"pause\", () => setIsPlaying(false));\n };\n }, []);\n\n return {\n buffered,\n bufferedPercentage: (buffered / (duration || 0)) * 100 || 0,\n };\n};\n","import { useEffect, useState, useCallback } from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useDownload = (videoRef: VideoRef) => {\n const [isDownloading, setIsDownloading] = useState(false);\n const [downloadProgress, setDownloadProgress] = useState(0);\n const [error, setError] = useState<string | null>(null);\n\n const downloadVideo = useCallback(\n async (filename?: string) => {\n if (!videoRef?.current) {\n setError(\"Video element not found\");\n return;\n }\n\n const video = videoRef.current;\n const videoSrc = video.src || video.currentSrc;\n\n if (!videoSrc) {\n setError(\"No video source found\");\n return;\n }\n\n try {\n setIsDownloading(true);\n setError(null);\n setDownloadProgress(0);\n\n // Fetch the video file\n const response = await fetch(videoSrc);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch video: ${response.statusText}`);\n }\n\n // Get the content length for progress tracking\n const contentLength = response.headers.get(\"content-length\");\n const total = contentLength ? parseInt(contentLength, 10) : 0;\n\n // Create a readable stream to track progress\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error(\"Failed to create download stream\");\n }\n\n const chunks: BlobPart[] = [];\n let receivedLength = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n chunks.push(value);\n receivedLength += value.length;\n\n if (total > 0) {\n const progress = (receivedLength / total) * 100;\n setDownloadProgress(Math.round(progress));\n }\n }\n\n // Combine chunks into a single blob\n const blob = new Blob(chunks, {\n type: response.headers.get(\"content-type\") || \"video/mp4\",\n });\n\n // Create download link\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n\n // Generate filename if not provided\n const defaultFilename = filename || `video-${Date.now()}.mp4`;\n link.download = defaultFilename;\n\n // Trigger download\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up\n URL.revokeObjectURL(url);\n\n setDownloadProgress(100);\n setIsDownloading(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Download failed\");\n setIsDownloading(false);\n setDownloadProgress(0);\n }\n },\n [videoRef]\n );\n\n // Alternative simple download method for direct video URLs\n const downloadDirect = useCallback(\n (filename?: string) => {\n if (!videoRef?.current) {\n setError(\"Video element not found\");\n return;\n }\n\n const video = videoRef.current;\n const videoSrc = video.src || video.currentSrc;\n\n if (!videoSrc) {\n setError(\"No video source found\");\n return;\n }\n\n try {\n setIsDownloading(true);\n setError(null);\n setDownloadProgress(0);\n\n const link = document.createElement(\"a\");\n link.href = videoSrc;\n link.download = filename || `video-${Date.now()}.mp4`;\n link.target = \"_blank\";\n\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n setIsDownloading(false);\n setDownloadProgress(100);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Download failed\");\n setIsDownloading(false);\n setDownloadProgress(0);\n }\n },\n [videoRef]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n setIsDownloading(false);\n setDownloadProgress(0);\n setError(null);\n };\n }, []);\n\n return {\n downloadVideo,\n downloadDirect,\n isDownloading,\n downloadProgress,\n error,\n resetError: () => setError(null),\n };\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useRange = (videoRef: VideoRef, range: [number, number]) => {\n React.useEffect(() => {\n if (!videoRef?.current || !range) return;\n\n const video = videoRef.current;\n\n if (video) {\n const handleTimeUpdate = () => {\n if (video.currentTime >= range[1]) {\n video.currentTime = range[0];\n } else if (video.currentTime <= range[0]) {\n video.currentTime = range[0];\n }\n };\n\n video.addEventListener(\"timeupdate\", handleTimeUpdate);\n\n return () => {\n video.removeEventListener(\"timeupdate\", handleTimeUpdate);\n };\n }\n }, [range, videoRef?.current]);\n};\n","import React, { RefObject, useRef } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useCurrentTime } from \"./hooks/use-current-time\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useDownload } from \"./hooks/use-download\";\nimport { useSpeed } from \"./hooks\";\nimport { useLoading } from \"./hooks/use-loading\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\ninterface SpeedProps extends Props {\n value: number;\n onClick?: () => void;\n}\n\nconst Speed = React.memo(\n ({ children, asChild, value, onClick, ...props }: SpeedProps) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { speed, onChangeSpeed } = useSpeed(\n videoRef as RefObject<HTMLVideoElement>\n );\n\n return (\n <Element\n {...props}\n value={value}\n onClick={() => {\n onChangeSpeed(value);\n onClick?.();\n }}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst PictureInPicture = React.memo(\n ({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n return (\n <Element {...props} onClick={togglePictureInPicture}>\n {children}\n </Element>\n );\n }\n);\n\nconst Download = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { downloadDirect } = useDownload(videoRef);\n\n return (\n <Element {...props} onClick={() => downloadDirect()}>\n {children}\n </Element>\n );\n});\n\ninterface LoadingProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Loading = React.memo(({ children, asChild, ...props }: LoadingProps) => {\n const Element = asChild ? Slot : \"div\";\n const { videoRef } = useVideo();\n\n const { isLoading } = useLoading(videoRef);\n\n return (\n <Element\n {...props}\n style={{ ...props.style, pointerEvents: \"none\" }}\n data-loading={isLoading}\n >\n {children}\n </Element>\n );\n});\n\ninterface ShadowProps extends React.ComponentProps<\"div\"> {}\n\nconst Shadow = ({ ...props }: ShadowProps) => {\n const { videoRef } = useVideo();\n\n const shadowVideoRef = useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n const video = videoRef?.current;\n if (shadowVideoRef.current && video) {\n let currentTime = 0;\n let isPlaying = false;\n let interval: ReturnType<typeof setInterval> | null = null;\n\n const startInterval = () => {\n if (interval) clearInterval(interval);\n interval = setInterval(() => {\n currentTime = video.currentTime;\n if (shadowVideoRef.current) {\n shadowVideoRef.current.currentTime = currentTime;\n }\n }, 100);\n };\n\n const stopInterval = () => {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n };\n\n const handlePlay = () => {\n isPlaying = true;\n startInterval();\n };\n\n const handlePause = () => {\n isPlaying = false;\n stopInterval();\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n stopInterval();\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n if (!videoRef?.current) return null;\n\n return (\n <div\n {...props}\n style={{\n ...props.style,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <video\n ref={shadowVideoRef}\n src={videoRef.current.src}\n muted\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n }}\n />\n </div>\n );\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n Speed,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n PictureInPicture,\n Download,\n Loading,\n Shadow,\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useLoading = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n const handleLoadStart = () => {\n setIsLoading(true);\n };\n\n const handleLoadedMetadata = () => {\n // Metadata loaded but video might not be ready to play yet\n // Keep loading true until canplay\n };\n\n const handleLoadedData = () => {\n // First frame loaded, but might still be buffering\n // Keep loading true until canplay\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n };\n\n const handleWaiting = () => {\n // Video is waiting for data (buffering)\n setIsLoading(true);\n };\n\n const handlePlaying = () => {\n // Video is playing, so it's not loading anymore\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const handleAbort = () => {\n setIsLoading(false);\n };\n\n const handleSuspend = () => {\n // Loading suspended (e.g., user paused)\n // Don't change loading state here\n };\n\n // Add event listeners\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"abort\", handleAbort);\n video.addEventListener(\"suspend\", handleSuspend);\n\n // Check initial state\n if (video.readyState >= 2) {\n setIsLoading(false);\n }\n\n return () => {\n // Remove event listeners\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"abort\", handleAbort);\n video.removeEventListener(\"suspend\", handleSuspend);\n };\n }, [videoRef]);\n\n return { isLoading };\n};\n"],"mappings":"mlBAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,cAAAE,GAAA,aAAAC,GAAA,mBAAAC,GAAA,eAAAC,GAAA,YAAAC,GAAA,SAAAC,GAAA,UAAAC,GAAA,qBAAAC,GAAA,SAAAC,GAAA,iBAAAC,GAAA,gBAAAC,GAAA,WAAAC,GAAA,UAAAC,GAAA,WAAAC,GAAA,UAAAC,EAAA,kBAAAC,EAAA,aAAAC,IAAA,eAAAC,GAAAnB,ICAA,IAAAoB,EAMO,sBAuKCC,EAAA,6BArJKC,KAAe,iBAAuC,IAAI,EAQ1DC,EAAgB,EAAAC,QAAM,KACjC,CAAC,CAAE,SAAAC,EAAU,OAAAC,EAAQ,QAAAC,EAAS,GAAGC,CAAM,IAA0B,CAC/D,GAAM,CAACC,EAAUC,CAAW,KAAI,YAAmB,CAAE,QAAS,IAAK,CAAC,EAC9D,CAACC,EAAOC,CAAQ,KAAI,YAAwB,IAAI,EAChD,CAACC,EAAWC,CAAY,KAAI,YAAS,EAAK,EAE1CC,KAAkB,UAAuB,IAAI,EAGnD,sBAAU,IAAM,CACdR,GAAA,MAAAA,EAAUI,EACZ,EAAG,CAACA,CAAK,CAAC,KAEV,aAAU,IAAM,CACd,IAAMK,EAAeD,EAAgB,QACrC,GAAIC,EAAc,CAChB,IAAMC,EAAWD,EAAa,iBAC5B,4BACF,EACME,EAAQF,EAAa,cACzB,oBACF,EAEA,GAAIC,EAAU,CACZ,IAAIE,EAAoD,KAClDC,EAAY,IACdC,EAAc,GAEZC,EAAa,IAAM,CAEnBH,IACF,aAAaA,CAAW,EACxBA,EAAc,MAIhBA,EAAc,WAAW,IAAM,CACzBE,GAEEH,GAAS,CAACA,EAAM,QAClBD,EAAS,QAASM,GAAY,CAC5BA,EAAQ,aAAa,cAAe,MAAM,CAC5C,CAAC,EAGLJ,EAAc,IAChB,EAAGC,CAAS,CACd,EAEMI,EAAe,IAAM,CACzBH,EAAc,GACdJ,EAAS,QAASM,GAAY,CAC5BA,EAAQ,gBAAgB,aAAa,CACvC,CAAC,EACDD,EAAW,CACb,EAEMG,EAAe,IAAM,CACzBJ,EAAc,GAEVF,IACF,aAAaA,CAAW,EACxBA,EAAc,MAGZD,GAAS,CAACA,EAAM,QAClBD,EAAS,QAASM,GAAY,CAC5BA,EAAQ,aAAa,cAAe,MAAM,CAC5C,CAAC,CAEL,EAEMG,EAAkB,IAAM,CACxBL,IAEFJ,EAAS,QAASM,GAAY,CACxBA,EAAQ,aAAa,aAAa,GACpCA,EAAQ,gBAAgB,aAAa,CAEzC,CAAC,EACDD,EAAW,EAEf,EAEMK,EAAa,IAAM,CAElBN,GACHJ,EAAS,QAASM,GAAY,CAC5BA,EAAQ,aAAa,cAAe,MAAM,CAC5C,CAAC,CAEL,EAEA,OAAAP,EAAa,iBAAiB,aAAcQ,CAAY,EACxDR,EAAa,iBAAiB,aAAcS,CAAY,EACxDT,EAAa,iBAAiB,YAAaU,CAAe,EAC1DR,EAAM,iBAAiB,QAASM,CAAY,EAC5CN,EAAM,iBAAiB,OAAQS,CAAU,EAGlC,IAAM,CACPR,GACF,aAAaA,CAAW,EAE1BH,EAAa,oBAAoB,aAAcQ,CAAY,EAC3DR,EAAa,oBAAoB,aAAcS,CAAY,EAC3DT,EAAa,oBAAoB,YAAaU,CAAe,EAC7DR,EAAM,oBAAoB,QAASM,CAAY,EAC/CN,EAAM,oBAAoB,OAAQS,CAAU,CAC9C,CACF,CACF,CACF,EAAG,CAAC,CAAC,KAEL,aAAU,IAAM,CACd,GAAId,EAAW,CACb,IAAMe,EAAeC,GAAsB,CApJnD,IAAAC,GAqJeA,EAAAf,EAAgB,UAAhB,MAAAe,EAAyB,SAASD,EAAM,SAC3Cf,EAAa,EAAK,CAEtB,EACA,gBAAS,iBAAiB,QAASc,CAAW,EAEvC,IAAM,CACX,SAAS,oBAAoB,QAASA,CAAW,CACnD,CACF,CACF,EAAG,CAACf,CAAS,CAAC,KAGZ,OAACX,EAAa,SAAb,CACC,MAAO,CACL,SAAAO,EACA,YAAAC,EACA,OAAQ,CAAE,YAAa,GAAM,GAAGJ,CAAO,EACvC,MAAAK,EACA,SAAAC,EACA,UAAAC,EACA,aAAAC,CACF,EAEA,mBAAC,OACC,IAAKC,EACL,2BAAwB,GACxB,QAAS,IAAMD,EAAa,EAAI,EAC/B,GAAGN,EAEH,SAAAH,EACH,EACF,CAEJ,CACF,EAEa0B,EAAW,IAAM,CAC5B,IAAMC,KAAU,cAAW9B,CAAY,EACvC,GAAI,CAAC8B,EACH,MAAM,IAAI,MAAM,8CAA8C,EAEhE,OAAOA,CACT,EChMA,IAAAC,EAMO,iBCNP,IAAAC,GAAkB,sBAGLC,GAAqB,CAChCC,EACAC,EACAC,IACG,CACH,GAAAC,QAAM,UAAU,IAAM,CACpB,GAAI,EAACH,GAAA,MAAAA,EAAU,UAAW,CAACC,EAAS,QAElB,SAAY,CAXlC,IAAAG,EAYM,GAAI,CACF,OAAMA,EAAAJ,EAAS,UAAT,YAAAI,EAAkB,OAC1B,OAASC,EAAO,CAEd,GAAIA,aAAiB,OAASA,EAAM,OAAS,mBAG3C,GAFAH,GAAA,MAAAA,EAAW,mBACX,QAAQ,MAAM,iBAAiB,EAC3BF,GAAA,MAAAA,EAAU,QAAS,CACrBA,EAAS,QAAQ,MAAQ,GACzB,GAAI,CACF,MAAMA,EAAS,QAAQ,KAAK,CAC9B,OAASM,EAAY,CACnB,QAAQ,MAAMA,CAAU,CAC1B,CACF,OAEA,QAAQ,MAAMD,CAAK,CAEvB,CACF,GAEU,CACZ,EAAG,CAACJ,EAASD,GAAA,YAAAA,EAAU,OAAO,CAAC,CACjC,ECnCA,IAAAO,GAA0B,iBAEbC,EAAa,CACxBC,EACAC,EACAC,EAAU,KACP,CACH,IAAMC,EAAiBC,GAAyB,CAC1CA,EAAM,MAAQJ,IAChBI,EAAM,eAAe,EACrBH,EAAKG,CAAK,EAEd,KAEA,cAAU,IAAM,CACd,GAAKF,EAEL,gBAAS,iBAAiB,UAAWC,CAAa,EAE3C,IAAM,CACX,SAAS,oBAAoB,UAAWA,CAAa,CACvD,CACF,EAAG,CAACH,EAAKC,EAAMC,CAAO,CAAC,CACzB,ECvBA,IAAAG,EAAkB,sBAGLC,EAAU,CAACC,EAAoBC,EAAQ,KAAO,CACzD,IAAMC,EAAc,EAAAC,QAAM,YAAY,IAAM,CACtCH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,aAAeC,EAEpC,EAAG,CAACD,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEhBI,EAAe,EAAAD,QAAM,YAAY,IAAM,CACvCH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,aAAeC,EAEpC,EAAG,CAACD,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEtB,MAAO,CAAE,YAAAE,EAAa,aAAAE,CAAa,CACrC,ECjBA,IAAAC,EAAkB,sBAGLC,EAAgBC,GAAuB,CAClD,GAAM,CAACC,EAAWC,CAAY,EAAI,EAAAC,QAAM,SAAS,EAAK,EAEhDC,EAAa,EAAAD,QAAM,YAAY,IAAM,CACrCH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,OACbA,EAAS,QAAQ,KAAK,EACtBA,EAAS,QAAQ,MAAM,EAE/B,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEhBK,EAAO,EAAAF,QAAM,YAAY,IAAM,CAC/BH,GAAA,MAAAA,EAAU,SACZA,EAAS,QAAQ,KAAK,CAE1B,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEhBM,EAAQ,EAAAH,QAAM,YAAY,IAAM,CAChCH,GAAA,MAAAA,EAAU,SACZA,EAAS,QAAQ,MAAM,CAE3B,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEtB,SAAAG,QAAM,UAAU,IAAM,CACpB,GAAI,EAACH,GAAA,MAAAA,EAAU,SAAS,OAExB,IAAMO,EAAa,IAAM,CACvBL,EAAa,EAAI,CACnB,EACMM,EAAc,IAAM,CACxBN,EAAa,EAAK,CACpB,EAIA,GAFAA,EAAa,EAACF,GAAA,MAAAA,EAAU,QAAQ,OAAM,EAElCA,GAAA,MAAAA,EAAU,QACZ,OAAAA,EAAS,QAAQ,iBAAiB,OAAQO,CAAU,EACpDP,EAAS,QAAQ,iBAAiB,QAASQ,CAAW,EAE/C,IAAM,CA1CnB,IAAAC,EAAAC,GA2CQD,EAAAT,EAAS,UAAT,MAAAS,EAAkB,oBAAoB,OAAQF,IAC9CG,EAAAV,EAAS,UAAT,MAAAU,EAAkB,oBAAoB,QAASF,EACjD,CAEJ,EAAG,CAACR,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEf,CAAE,WAAAI,EAAY,UAAAH,EAAW,KAAAI,EAAM,MAAAC,CAAM,CAC9C,EClDA,IAAAK,EAAkB,sBAGLC,EAAiBC,GAAuB,CACnD,GAAM,CAACC,EAASC,CAAU,EAAI,EAAAC,QAAM,SAAS,EAAK,EAE5CC,EAAa,EAAAD,QAAM,YAAY,IAAM,CACrCH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,MAAQ,CAACA,EAAS,QAAQ,MAE/C,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEhBK,EAAO,EAAAF,QAAM,YAAY,IAAM,CAC/BH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,MAAQ,GAE7B,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEhBM,EAAS,EAAAH,QAAM,YAAY,IAAM,CACjCH,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,MAAQ,GAE7B,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEtB,SAAAG,QAAM,UAAU,IAAM,CACpB,GAAI,EAACH,GAAA,MAAAA,EAAU,SAAS,OAGxBE,EAAWF,EAAS,QAAQ,KAAK,EAEjC,IAAMO,EAAqB,IAAM,CAC3BP,EAAS,SACXE,EAAWF,EAAS,QAAQ,KAAK,CAErC,EAEA,OAAAA,EAAS,QAAQ,iBAAiB,eAAgBO,CAAkB,EAE7D,IAAM,CAtCjB,IAAAC,GAuCMA,EAAAR,EAAS,UAAT,MAAAQ,EAAkB,oBAAoB,eAAgBD,EACxD,CACF,EAAG,CAACP,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEf,CAAE,WAAAI,EAAY,QAAAH,EAAS,KAAAI,EAAM,OAAAC,CAAO,CAC7C,EC5CA,IAAAG,EAAkB,sBAGZC,EAAiBC,GAAuB,CAC5C,GAAM,CAACC,EAAcC,CAAe,EAAI,EAAAC,QAAM,SAAS,EAAK,EACtDC,EAAoB,EAAAD,QAAM,OAQtB,IAAI,EAEd,EAAAA,QAAM,UAAU,IAAM,CACpB,IAAME,EAAyB,IAAM,CACnC,IAAMC,EAAwB,CAAC,CAAC,SAAS,kBACzCJ,EAAgBI,CAAqB,EAGrC,IAAMC,EAAQP,GAAA,YAAAA,EAAU,QACpBO,IACED,GAEFF,EAAkB,QAAU,CAC1B,UAAWG,EAAM,MAAM,WAAa,QACpC,aAAcA,EAAM,MAAM,cAAgB,GAC1C,MAAOA,EAAM,MAAM,OAAS,GAC5B,OAAQA,EAAM,MAAM,QAAU,GAC9B,SAAUA,EAAM,MAAM,UAAY,GAClC,UAAWA,EAAM,MAAM,WAAa,GACpC,OAAQA,EAAM,MAAM,QAAU,EAChC,EAEAA,EAAM,MAAM,UAAY,UACxBA,EAAM,MAAM,aAAe,IAC3BA,EAAM,MAAM,MAAQ,OACpBA,EAAM,MAAM,OAAS,OACrBA,EAAM,MAAM,SAAW,OACvBA,EAAM,MAAM,UAAY,OACxBA,EAAM,MAAM,OAAS,KAGjBH,EAAkB,UACpBG,EAAM,MAAM,UAAYH,EAAkB,QAAQ,UAClDG,EAAM,MAAM,aAAeH,EAAkB,QAAQ,aACrDG,EAAM,MAAM,MAAQH,EAAkB,QAAQ,MAC9CG,EAAM,MAAM,OAASH,EAAkB,QAAQ,OAC/CG,EAAM,MAAM,SAAWH,EAAkB,QAAQ,SACjDG,EAAM,MAAM,UAAYH,EAAkB,QAAQ,UAClDG,EAAM,MAAM,OAASH,EAAkB,QAAQ,OAC/CA,EAAkB,QAAU,MAIpC,EAEA,gBAAS,iBAAiB,mBAAoBC,CAAsB,EAC7D,IACL,SAAS,oBAAoB,mBAAoBA,CAAsB,CAC3E,EAAG,CAACL,CAAQ,CAAC,EAEb,IAAMQ,EAAmB,IAAM,CAC7B,IAAMC,EAAW,iCAAiC,KAAK,UAAU,SAAS,EACpEF,EAAQP,GAAA,YAAAA,EAAU,QAExB,GAAIO,GAASE,GACX,GAAKF,EAAc,sBAAuB,CACvCA,EAAc,sBAAsB,EACrC,MACF,SAAWA,EAAM,kBAAmB,CAClCA,EAAM,kBAAkB,EACxB,MACF,EAGF,IAAMG,EAAiBH,GAAA,YAAAA,EAAO,QAC5B,8BAGEG,IACGT,EAGH,SAAS,eAAe,EAFxBS,EAAe,kBAAkB,EAKvC,EAEA,MAAO,CAAE,aAAcT,GAAA,KAAAA,EAAgB,GAAO,iBAAAO,CAAiB,CACjE,ECzFO,IAAMG,EAAuBC,IAkD3B,CACL,uBAlD6B,SAAY,CACzC,IAAMC,EAAQD,GAAA,YAAAA,EAAU,QACxB,GAAKC,EAEL,GAAI,CACE,SAAS,wBACX,MAAM,SAAS,qBAAqB,EAEpC,MAAMA,EAAM,wBAAwB,CAExC,OAASC,EAAO,CAMd,GAJiB,iCAAiC,KAChD,UAAU,SACZ,EAGOD,EAAc,sBAChBA,EAAc,sBAAsB,EAC5BA,EAAM,mBACfA,EAAM,kBAAkB,MAErB,CACL,IAAME,EAAiBF,EAAM,QAC3B,4BACF,EACIE,IACG,SAAS,kBAGZ,MAAM,SAAS,eAAe,EAF9B,MAAMA,EAAe,kBAAkB,EAK7C,CACF,CACF,EAgBE,wBAd8B,SAAY,CAC1C,IAAMF,EAAQD,GAAA,YAAAA,EAAU,QACnBC,GACL,MAAMA,EAAM,wBAAwB,CACtC,EAWE,qBAT2B,SAAY,CACzBD,GAAA,MAAAA,EAAU,SAExB,MAAM,SAAS,qBAAqB,CACtC,CAMA,GChDK,IAAMI,GAAY,IAAM,CAC7B,GAAM,CAAE,SAAAC,CAAS,EAAIC,EAAS,EAExB,CAAE,YAAAC,EAAa,aAAAC,CAAa,EAAIC,EAAQJ,CAAQ,EAChD,CAAE,WAAAK,CAAW,EAAIC,EAAaN,CAAQ,EACtC,CAAE,WAAAO,CAAW,EAAIC,EAAcR,CAAQ,EACvC,CAAE,iBAAAS,CAAiB,EAAIC,EAAcV,CAAQ,EAC7C,CAAE,uBAAAW,CAAuB,EAAIC,EAAoBZ,CAAQ,EAE/D,OAAAa,EAAW,aAAc,IAAM,CAC7BX,EAAY,CACd,CAAC,EACDW,EAAW,YAAa,IAAM,CAC5BV,EAAa,CACf,CAAC,EACDU,EAAW,IAAK,IAAM,CACpBR,EAAW,CACb,CAAC,EACDQ,EAAW,IAAK,IAAM,CACpBN,EAAW,CACb,CAAC,EACDM,EAAW,IAAK,IAAM,CACpBJ,EAAiB,CACnB,CAAC,EACDI,EAAW,IAAK,IAAM,CACpBF,EAAuB,CACzB,CAAC,EAEM,IACT,ECrCA,IAAAG,GAAkB,sBAGLC,GAAuB,CAClCC,EACAC,EACAC,EAAU,KACP,CACH,GAAAC,QAAM,UAAU,IAAM,CACpB,GAAI,EAACH,GAAA,MAAAA,EAAU,UAAW,CAACE,EAAS,OAEpC,IAAME,EAAW,IAAI,qBAClBC,GAAY,CACXA,EAAQ,QAASC,GAAU,CAbnC,IAAAC,EAceP,GAAA,MAAAA,EAAU,UAEXM,EAAM,eACRN,EAAS,QAAQ,KAAK,EAAE,MAAOQ,GAAU,CAClCR,EAAS,UAEdA,EAAS,QAAQ,MAAM,EACvBA,EAAS,QAAQ,MAAQ,GACzBA,EAAS,QAAQ,KAAK,EACtB,QAAQ,MAAMQ,CAAK,EACrB,CAAC,GAEDD,EAAAP,EAAS,UAAT,MAAAO,EAAkB,QAEtB,CAAC,CACH,EACA,CAAE,UAAWN,GAAA,KAAAA,EAAa,EAAI,CAChC,EAEA,OAAAG,EAAS,QAAQJ,GAAA,YAAAA,EAAU,OAAO,EAE3B,IAAM,CACXI,EAAS,WAAW,CACtB,CACF,EAAG,CAACJ,GAAA,YAAAA,EAAU,OAAO,CAAC,CACxB,ECvCA,IAAAS,GAAkB,sBCAlB,IAAAC,EAAkB,sBAGLC,GAAYC,GAAuB,CAC9C,GAAM,CAACC,EAAOC,CAAQ,EAAI,EAAAC,QAAM,SAAS,CAAC,EAEpCC,EAAiBH,GAAkB,CACvCC,EAASD,CAAK,CAChB,EAGA,SAAAE,QAAM,UAAU,IAAM,CACfH,GAAA,MAAAA,EAAU,SACfE,EAASF,EAAS,QAAQ,YAAY,CACxC,EAAG,CAACA,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEtB,EAAAG,QAAM,UAAU,IAAM,CACfH,GAAA,MAAAA,EAAU,UAEfA,EAAS,QAAQ,aAAeC,EAClC,EAAG,CAACA,EAAOD,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEtB,CAAE,MAAAC,EAAO,cAAAG,CAAc,CAChC,ECvBA,IAAAC,GAAkB,sBCAlB,IAAAC,GAAkB,sBCAlB,IAAAC,GAA+C,iBCA/C,IAAAC,GAAkB,sBCAlB,IAAAC,GAAkB,sBCAlB,IAAAC,EAAiD,iBAGpCC,GAAeC,GAAuB,CACjD,GAAM,CAACC,EAAeC,CAAgB,KAAI,YAAS,EAAK,EAClD,CAACC,EAAkBC,CAAmB,KAAI,YAAS,CAAC,EACpD,CAACC,EAAOC,CAAQ,KAAI,YAAwB,IAAI,EAEhDC,KAAgB,eACpB,MAAOC,GAAsB,CATjC,IAAAC,EAUM,GAAI,EAACT,GAAA,MAAAA,EAAU,SAAS,CACtBM,EAAS,yBAAyB,EAClC,MACF,CAEA,IAAMI,EAAQV,EAAS,QACjBW,EAAWD,EAAM,KAAOA,EAAM,WAEpC,GAAI,CAACC,EAAU,CACbL,EAAS,uBAAuB,EAChC,MACF,CAEA,GAAI,CACFJ,EAAiB,EAAI,EACrBI,EAAS,IAAI,EACbF,EAAoB,CAAC,EAGrB,IAAMQ,EAAW,MAAM,MAAMD,CAAQ,EAErC,GAAI,CAACC,EAAS,GACZ,MAAM,IAAI,MAAM,0BAA0BA,EAAS,UAAU,EAAE,EAIjE,IAAMC,EAAgBD,EAAS,QAAQ,IAAI,gBAAgB,EACrDE,EAAQD,EAAgB,SAASA,EAAe,EAAE,EAAI,EAGtDE,GAASN,EAAAG,EAAS,OAAT,YAAAH,EAAe,YAC9B,GAAI,CAACM,EACH,MAAM,IAAI,MAAM,kCAAkC,EAGpD,IAAMC,EAAqB,CAAC,EACxBC,EAAiB,EAErB,OAAa,CACX,GAAM,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAMJ,EAAO,KAAK,EAE1C,GAAIG,EAAM,MAKV,GAHAF,EAAO,KAAKG,CAAK,EACjBF,GAAkBE,EAAM,OAEpBL,EAAQ,EAAG,CACb,IAAMM,EAAYH,EAAiBH,EAAS,IAC5CV,EAAoB,KAAK,MAAMgB,CAAQ,CAAC,CAC1C,CACF,CAGA,IAAMC,EAAO,IAAI,KAAKL,EAAQ,CAC5B,KAAMJ,EAAS,QAAQ,IAAI,cAAc,GAAK,WAChD,CAAC,EAGKU,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAO,SAAS,cAAc,GAAG,EACvCA,EAAK,KAAOD,EAGZ,IAAME,EAAkBhB,GAAY,SAAS,KAAK,IAAI,CAAC,OACvDe,EAAK,SAAWC,EAGhB,SAAS,KAAK,YAAYD,CAAI,EAC9BA,EAAK,MAAM,EACX,SAAS,KAAK,YAAYA,CAAI,EAG9B,IAAI,gBAAgBD,CAAG,EAEvBlB,EAAoB,GAAG,EACvBF,EAAiB,EAAK,CACxB,OAASuB,EAAK,CACZnB,EAASmB,aAAe,MAAQA,EAAI,QAAU,iBAAiB,EAC/DvB,EAAiB,EAAK,EACtBE,EAAoB,CAAC,CACvB,CACF,EACA,CAACJ,CAAQ,CACX,EAGM0B,KAAiB,eACpBlB,GAAsB,CACrB,GAAI,EAACR,GAAA,MAAAA,EAAU,SAAS,CACtBM,EAAS,yBAAyB,EAClC,MACF,CAEA,IAAMI,EAAQV,EAAS,QACjBW,EAAWD,EAAM,KAAOA,EAAM,WAEpC,GAAI,CAACC,EAAU,CACbL,EAAS,uBAAuB,EAChC,MACF,CAEA,GAAI,CACFJ,EAAiB,EAAI,EACrBI,EAAS,IAAI,EACbF,EAAoB,CAAC,EAErB,IAAMmB,EAAO,SAAS,cAAc,GAAG,EACvCA,EAAK,KAAOZ,EACZY,EAAK,SAAWf,GAAY,SAAS,KAAK,IAAI,CAAC,OAC/Ce,EAAK,OAAS,SAEd,SAAS,KAAK,YAAYA,CAAI,EAC9BA,EAAK,MAAM,EACX,SAAS,KAAK,YAAYA,CAAI,EAE9BrB,EAAiB,EAAK,EACtBE,EAAoB,GAAG,CACzB,OAASqB,EAAK,CACZnB,EAASmB,aAAe,MAAQA,EAAI,QAAU,iBAAiB,EAC/DvB,EAAiB,EAAK,EACtBE,EAAoB,CAAC,CACvB,CACF,EACA,CAACJ,CAAQ,CACX,EAGA,sBAAU,IACD,IAAM,CACXE,EAAiB,EAAK,EACtBE,EAAoB,CAAC,EACrBE,EAAS,IAAI,CACf,EACC,CAAC,CAAC,EAEE,CACL,cAAAC,EACA,eAAAmB,EACA,cAAAzB,EACA,iBAAAE,EACA,MAAAE,EACA,WAAY,IAAMC,EAAS,IAAI,CACjC,CACF,ECzJA,IAAAqB,GAAkB,sBlB8HZ,IAAAC,EAAA,6BAtGOC,KAAQ,cACnB,CACE,CACE,IAAAC,EACA,SAAAC,EACA,aAAAC,EACA,SAAAC,EACA,QAAAC,EAAU,WACV,kBAAAC,EACA,OAAAC,EACA,GAAGC,CACL,EACAC,IACG,CACH,GAAM,CAAE,SAAAC,EAAU,YAAAC,EAAa,OAAAC,EAAQ,SAAAC,EAAU,MAAAC,EAAO,UAAAC,CAAU,EAChEC,EAAS,EAELC,KAAW,UAAyB,IAAI,EACxCC,KAAiB,UAAO,EAAK,EAC7BC,KAAW,UAAsB,IAAI,EACrCC,KAAe,UAA6C,IAAI,EAGhEC,EACJd,GACAA,EAAO,QAAU,GACjB,OAAOA,EAAO,CAAC,GAAM,UACrB,OAAOA,EAAO,CAAC,GAAM,UACrBA,EAAO,CAAC,GAAK,GACbA,EAAO,CAAC,EAAIA,EAAO,CAAC,GACpB,SAASA,EAAO,CAAC,CAAC,GAClB,SAASA,EAAO,CAAC,CAAC,EAGde,EAAaD,EAAed,EAAO,CAAC,EAAI,OACxCgB,EAAWF,EAAed,EAAO,CAAC,EAAI,UAE5C,aAAU,IAAM,CACd,IAAMiB,EAAQP,EAAS,QACjBQ,EAAgBhB,EAEtB,OAAIgB,EACFd,EAAYc,CAA4C,EAEpDD,GACFb,EAAY,CAAE,QAASa,CAAM,CAAC,EAK3B,IAAM,CACXN,EAAe,QAAU,GACrBC,EAAS,UAAY,OACvB,qBAAqBA,EAAS,OAAO,EACrCA,EAAS,QAAU,MAEjBC,EAAa,UAAY,OAC3B,aAAaA,EAAa,OAAO,EACjCA,EAAa,QAAU,KAE3B,CACF,EAAG,CAACnB,EAAKQ,EAAKE,CAAW,CAAC,KAG1B,aAAU,IACD,IAAM,CACPQ,EAAS,UAAY,OACvB,qBAAqBA,EAAS,OAAO,EACrCA,EAAS,QAAU,MAEjBC,EAAa,UAAY,OAC3B,aAAaA,EAAa,OAAO,EACjCA,EAAa,QAAU,KAE3B,EACC,CAAC,CAAC,EAELM,GACEhB,EACAR,IAAa,SAAWM,EAAM,QAAU,OACxCK,CACF,EAEAc,GACEjB,EACA,OAAOJ,GAAsB,SACzBA,EACCA,EAEC,OADA,GAEN,CAAC,CAACA,CACJ,EAEA,IAAMsB,KAAS,eAAY,IAAM,CArHrC,IAAAC,EAAAC,EAAAC,GAsHUF,EAAAnB,GAAA,YAAAA,EAAU,UAAV,MAAAmB,EAAmB,QACrBC,EAAApB,EAAS,UAAT,MAAAoB,EAAkB,QAElBC,EAAArB,GAAA,YAAAA,EAAU,UAAV,MAAAqB,EAAmB,OAEvB,EAAG,CAACrB,CAAQ,CAAC,EAEb,SACE,oBACE,oBAAC,SACC,IAAKD,GAAOQ,EACZ,mBAAgB,GAChB,IAAKhB,EACL,QAASW,GAAA,MAAAA,EAAQ,YAAcgB,EAAS,OACxC,SAAU1B,IAAa,QAAU,GAAOA,EACxC,QAASG,EACT,YAAW,GACX,iBAAmB2B,GAAM,CAvInC,IAAAH,EA0IY,IAAML,EAAQQ,EAAE,cAEdX,GACAC,IAAe,QACfC,IAAa,SAGbC,EAAM,YAAcF,IAEtBO,EAAArB,EAAM,mBAAN,MAAAqB,EAAA,KAAArB,EAAyBwB,EAC3B,EACA,UAAYA,GAAM,CArJ5B,IAAAH,EAwJY,IAAML,EAAQQ,EAAE,cAChB,GACEX,GACAC,IAAe,QACfC,IAAa,OACb,CACA,IAAMU,EAAcT,EAAM,aAEtBS,EAAcX,GAAcW,EAAcV,KAC5CC,EAAM,YAAcF,EAExB,EACAO,EAAArB,EAAM,YAAN,MAAAqB,EAAA,KAAArB,EAAkBwB,EACpB,EACA,SAAWA,GAAM,CAtK3B,IAAAH,EAwKY,IAAML,EAAQQ,EAAE,cAChB,GACEX,GACAC,IAAe,QACfC,IAAa,QACbC,EAAM,OACN,CACA,IAAMS,EAAcT,EAAM,YAC1B,IAAIS,EAAcX,GAAcW,EAAcV,IAExC,KAAK,IAAIU,EAAcX,CAAU,EAAI,IAAM,CAC7CJ,EAAe,QAAU,GACzBM,EAAM,YAAcF,EAGhBH,EAAS,UAAY,MACvB,qBAAqBA,EAAS,OAAO,EAEvCA,EAAS,QAAU,sBAAsB,IAAM,CAC7CD,EAAe,QAAU,GACzBC,EAAS,QAAU,IACrB,CAAC,EACD,MACF,CAEJ,CACAD,EAAe,QAAU,IACzBW,EAAArB,EAAM,WAAN,MAAAqB,EAAA,KAAArB,EAAiBwB,EACnB,EACA,aAAeA,GAAM,CArM/B,IAAAH,EAsMY,IAAML,EAAQQ,EAAE,cAEhB,GACEX,GACAC,IAAe,QACfC,IAAa,QACb,CAACL,EAAe,QAChB,CACA,IAAMe,EAAcT,EAAM,YAGtB,CAACA,EAAM,QAAUS,GAAeV,GAClCL,EAAe,QAAU,GACzBM,EAAM,YAAcF,EAIhBF,EAAa,UAAY,MAC3B,aAAaA,EAAa,OAAO,EAEnCD,EAAS,QAAU,sBAAsB,IAAM,CAC7CC,EAAa,QAAU,WAAW,IAAM,CAClCF,EAAe,UACjBA,EAAe,QAAU,IAE3BE,EAAa,QAAU,IACzB,EAAG,GAAG,EACND,EAAS,QAAU,IACrB,CAAC,GAIDK,EAAM,SACLS,EAAcX,GAAcW,EAAcV,KAIzC,KAAK,IAAIU,EAAcX,CAAU,EAAI,KACrCW,EAAcV,KAEdL,EAAe,QAAU,GACzBM,EAAM,YAAcF,EAGhBH,EAAS,UAAY,MACvB,qBAAqBA,EAAS,OAAO,EAEnCC,EAAa,UAAY,MAC3B,aAAaA,EAAa,OAAO,EAEnCD,EAAS,QAAU,sBAAsB,IAAM,CAC7CD,EAAe,QAAU,GACzBC,EAAS,QAAU,IACrB,CAAC,EAGP,EAEAU,EAAArB,EAAM,eAAN,MAAAqB,EAAA,KAAArB,EAAqBwB,EACvB,EACC,GAAGxB,EACN,EAECJ,GAAYW,MAAa,OAACmB,GAAA,EAAU,EAEpCpB,IAAU,mBACT,OAAOX,GAAiB,YACxBA,EAAa,IAAM,CACbO,GAAA,MAAAA,EAAU,UACZA,EAAS,QAAQ,MAAQ,CAACA,EAAS,QAAQ,OAE7CG,EAAS,IAAI,CACf,CAAC,GACL,CAEJ,CACF,EAEAb,EAAM,YAAc,QmBpRpB,IAAAmC,EAAyC,sBAEzCC,EAAqB,gCCFrB,IAAAC,EAAkB,sBAGLC,GAAcC,GAAuB,CAChD,GAAM,CAACC,EAAWC,CAAY,EAAI,EAAAC,QAAM,SAAS,EAAK,EAEtD,SAAAA,QAAM,UAAU,IAAM,CACpB,GAAI,EAACH,GAAA,MAAAA,EAAU,SAAS,OAExB,IAAMI,EAAQJ,EAAS,QAEjBK,EAAkB,IAAM,CAC5BH,EAAa,EAAI,CACnB,EAEMI,EAAuB,IAAM,CAGnC,EAEMC,EAAmB,IAAM,CAG/B,EAEMC,EAAgB,IAAM,CAC1BN,EAAa,EAAK,CACpB,EAEMO,EAAuB,IAAM,CACjCP,EAAa,EAAK,CACpB,EAEMQ,EAAgB,IAAM,CAE1BR,EAAa,EAAI,CACnB,EAEMS,EAAgB,IAAM,CAE1BT,EAAa,EAAK,CACpB,EAEMU,EAAc,IAAM,CACxBV,EAAa,EAAK,CACpB,EAEMW,EAAc,IAAM,CACxBX,EAAa,EAAK,CACpB,EAEMY,EAAgB,IAAM,CAG5B,EAGA,OAAAV,EAAM,iBAAiB,YAAaC,CAAe,EACnDD,EAAM,iBAAiB,iBAAkBE,CAAoB,EAC7DF,EAAM,iBAAiB,aAAcG,CAAgB,EACrDH,EAAM,iBAAiB,UAAWI,CAAa,EAC/CJ,EAAM,iBAAiB,iBAAkBK,CAAoB,EAC7DL,EAAM,iBAAiB,UAAWM,CAAa,EAC/CN,EAAM,iBAAiB,UAAWO,CAAa,EAC/CP,EAAM,iBAAiB,QAASQ,CAAW,EAC3CR,EAAM,iBAAiB,QAASS,CAAW,EAC3CT,EAAM,iBAAiB,UAAWU,CAAa,EAG3CV,EAAM,YAAc,GACtBF,EAAa,EAAK,EAGb,IAAM,CAEXE,EAAM,oBAAoB,YAAaC,CAAe,EACtDD,EAAM,oBAAoB,iBAAkBE,CAAoB,EAChEF,EAAM,oBAAoB,aAAcG,CAAgB,EACxDH,EAAM,oBAAoB,UAAWI,CAAa,EAClDJ,EAAM,oBAAoB,iBAAkBK,CAAoB,EAChEL,EAAM,oBAAoB,UAAWM,CAAa,EAClDN,EAAM,oBAAoB,UAAWO,CAAa,EAClDP,EAAM,oBAAoB,QAASQ,CAAW,EAC9CR,EAAM,oBAAoB,QAASS,CAAW,EAC9CT,EAAM,oBAAoB,UAAWU,CAAa,CACpD,CACF,EAAG,CAACd,CAAQ,CAAC,EAEN,CAAE,UAAAC,CAAU,CACrB,EDnEM,IAAAc,EAAA,6BAHAC,GAAW,EAAAC,QAAM,KACrB,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,OAE3B,OAAC,OAAI,2BAAwB,GAAE,GAAGA,EAC/B,SAAAF,EACH,CAGN,EAOMG,GAAO,EAAAJ,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CAClE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,KAAAC,CAAK,EAAIC,EAAaH,CAAuC,EAErE,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASK,EAC1B,SAAAP,EACH,CAEJ,CAAC,EAEKS,GAAQ,EAAAV,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CACnE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,MAAAI,CAAM,EAAIF,EAAaH,CAAuC,EAEtE,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASQ,EAC1B,SAAAV,EACH,CAEJ,CAAC,EAEKW,GAAO,EAAAZ,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CAClE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,KAAAM,CAAK,EAAIC,EAAcR,CAAuC,EAEtE,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASU,EAC1B,SAAAZ,EACH,CAEJ,CAAC,EAEKc,GAAS,EAAAf,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CACpE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,OAAAS,CAAO,EAAIF,EAAcR,CAAuC,EAExE,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASa,EAC1B,SAAAf,EACH,CAEJ,CAAC,EAOKgB,GAAQ,EAAAjB,QAAM,KAClB,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,MAAAgB,EAAO,QAAAC,EAAS,GAAGhB,CAAM,IAAkB,CAC/D,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,MAAAa,EAAO,cAAAC,CAAc,EAAIC,GAC/BhB,CACF,EAEA,SACE,OAACD,EAAA,CACE,GAAGF,EACJ,MAAOe,EACP,QAAS,IAAM,CACbG,EAAcH,CAAK,EACnBC,GAAA,MAAAA,GACF,EAEC,SAAAlB,EACH,CAEJ,CACF,EAEMsB,GAAc,EAAAvB,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CACzE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,YAAAiB,CAAY,EAAIC,EAAQnB,EAAyC,EAAE,EAE3E,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASqB,EAC1B,SAAAvB,EACH,CAEJ,CAAC,EAEKyB,GAAe,EAAA1B,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CAC1E,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,aAAAoB,CAAa,EAAIF,EAAQnB,EAAyC,EAAE,EAE5E,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAASwB,EAC1B,SAAA1B,EACH,CAEJ,CAAC,EAEK2B,GAAa,EAAA5B,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CACxE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,iBAAAsB,CAAiB,EAAIC,EAAcxB,CAAQ,EAEnD,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAAS0B,EAC1B,SAAA5B,EACH,CAEJ,CAAC,EAEK8B,GAAiB,EAAA/B,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CAC5E,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,iBAAAsB,CAAiB,EAAIC,EAAcxB,CAAQ,EAEnD,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAAS0B,EAC1B,SAAA5B,EACH,CAEJ,CAAC,EAEK+B,GAAmB,EAAAhC,QAAM,KAC7B,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CAC1C,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,uBAAA0B,CAAuB,EAAIC,EAAoB5B,CAAQ,EAE/D,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAAS8B,EAC1B,SAAAhC,EACH,CAEJ,CACF,EAEMkC,GAAW,EAAAnC,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAa,CACtE,IAAME,EAAUH,EAAU,OAAO,SAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,eAAA6B,CAAe,EAAIC,GAAY/B,CAAQ,EAE/C,SACE,OAACD,EAAA,CAAS,GAAGF,EAAO,QAAS,IAAMiC,EAAe,EAC/C,SAAAnC,EACH,CAEJ,CAAC,EAOKqC,GAAU,EAAAtC,QAAM,KAAK,CAAC,CAAE,SAAAC,EAAU,QAAAC,EAAS,GAAGC,CAAM,IAAoB,CAC5E,IAAME,EAAUH,EAAU,OAAO,MAC3B,CAAE,SAAAI,CAAS,EAAIC,EAAS,EAExB,CAAE,UAAAgC,CAAU,EAAIC,GAAWlC,CAAQ,EAEzC,SACE,OAACD,EAAA,CACE,GAAGF,EACJ,MAAO,CAAE,GAAGA,EAAM,MAAO,cAAe,MAAO,EAC/C,eAAcoC,EAEb,SAAAtC,EACH,CAEJ,CAAC,EAIKwC,GAAS,CAAC,CAAE,GAAGtC,CAAM,IAAmB,CAC5C,GAAM,CAAE,SAAAG,CAAS,EAAIC,EAAS,EAExBmC,KAAiB,UAAyB,IAAI,EA+CpD,OA7CA,EAAA1C,QAAM,UAAU,IAAM,CACpB,IAAM2C,EAAQrC,GAAA,YAAAA,EAAU,QACxB,GAAIoC,EAAe,SAAWC,EAAO,CACnC,IAAIC,EAAc,EACdC,EAAY,GACZC,EAAkD,KAEhDC,EAAgB,IAAM,CACtBD,GAAU,cAAcA,CAAQ,EACpCA,EAAW,YAAY,IAAM,CAC3BF,EAAcD,EAAM,YAChBD,EAAe,UACjBA,EAAe,QAAQ,YAAcE,EAEzC,EAAG,GAAG,CACR,EAEMI,EAAe,IAAM,CACrBF,IACF,cAAcA,CAAQ,EACtBA,EAAW,KAEf,EAEMG,EAAa,IAAM,CACvBJ,EAAY,GACZE,EAAc,CAChB,EAEMG,EAAc,IAAM,CACxBL,EAAY,GACZG,EAAa,CACf,EAEA,OAAAL,EAAM,iBAAiB,OAAQM,CAAU,EACzCN,EAAM,iBAAiB,QAASO,CAAW,EAEpC,IAAM,CACXF,EAAa,EACbL,EAAM,oBAAoB,OAAQM,CAAU,EAC5CN,EAAM,oBAAoB,QAASO,CAAW,CAChD,CACF,CACF,EAAG,CAAC5C,GAAA,YAAAA,EAAU,OAAO,CAAC,EAEjBA,GAAA,MAAAA,EAAU,WAGb,OAAC,OACE,GAAGH,EACJ,MAAO,CACL,GAAGA,EAAM,MACT,SAAU,WACV,IAAK,EACL,KAAM,EACN,MAAO,OACP,OAAQ,OACR,cAAe,MACjB,EAEA,mBAAC,SACC,IAAKuC,EACL,IAAKpC,EAAS,QAAQ,IACtB,MAAK,GACL,YAAW,GACX,MAAO,CACL,MAAO,OACP,OAAQ,OACR,UAAW,OACb,EACF,EACF,EA1B6B,IA4BjC","names":["index_exports","__export","Controls","Download","ExitFullscreen","Fullscreen","Loading","Mute","Pause","PictureInPicture","Play","SeekBackward","SeekForward","Shadow","Speed","Unmute","Video","VideoProvider","useVideo","__toCommonJS","import_react","import_jsx_runtime","VideoContext","VideoProvider","React","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","import_react","import_react","useAutoplayByForce","videoRef","enabled","setError","React","_a","error","retryError","import_react","useHotKeys","key","func","enabled","handleKeyDown","event","import_react","useSeek","videoRef","value","seekForward","React","seekBackward","import_react","usePlayPause","videoRef","isPlaying","setIsPlaying","React","togglePlay","play","pause","handlePlay","handlePause","_a","_b","import_react","useMuteUnmute","videoRef","isMuted","setIsMuted","React","toggleMute","mute","unmute","handleVolumeChange","_a","import_react","useFullscreen","videoRef","isFullscreen","setIsFullscreen","React","previousStylesRef","handleFullscreenChange","isCurrentlyFullscreen","video","toggleFullscreen","isSafari","videoContainer","usePictureInPicture","videoRef","video","error","videoContainer","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","import_react","useAutoplayOnVisible","videoRef","threshold","enabled","React","observer","entries","entry","_a","error","import_react","import_react","useSpeed","videoRef","speed","setSpeed","React","onChangeSpeed","import_react","import_react","import_react","import_react","import_react","import_react","useDownload","videoRef","isDownloading","setIsDownloading","downloadProgress","setDownloadProgress","error","setError","downloadVideo","filename","_a","video","videoSrc","response","contentLength","total","reader","chunks","receivedLength","done","value","progress","blob","url","link","defaultFilename","err","downloadDirect","import_react","import_jsx_runtime","Video","src","autoPlay","muteFallback","controls","preload","autoPlayOnVisible","ranges","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","isAdjustingRef","rafIdRef","timeoutIdRef","isValidRange","rangeStart","rangeEnd","video","thirdPartyRef","useAutoplayByForce","useAutoplayOnVisible","onPlay","_a","_b","_c","e","currentTime","Keyboards","import_react","import_react_slot","import_react","useLoading","videoRef","isLoading","setIsLoading","React","video","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handleError","handleAbort","handleSuspend","import_jsx_runtime","Controls","React","children","asChild","props","Play","Element","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","Speed","value","onClick","speed","onChangeSpeed","useSpeed","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","PictureInPicture","togglePictureInPicture","usePictureInPicture","Download","downloadDirect","useDownload","Loading","isLoading","useLoading","Shadow","shadowVideoRef","video","currentTime","isPlaying","interval","startInterval","stopInterval","handlePlay","handlePause"]}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use client";import{a as q,b as M,c as x,d as A,e as S,f as I,g as O,h as z,j as U,p as B}from"./chunk-XV6ODTKT.js";import _,{createContext as $,useContext as ee,useEffect as N,useRef as te,useState as D}from"react";import{jsx as K}from"react/jsx-runtime";var W=$(null),ne=_.memo(({children:n,config:r,onError:t,...e})=>{let[i,o]=D({current:null}),[s,c]=D(null),[E,u]=D(!1),b=te(null);return N(()=>{t==null||t(s)},[s]),N(()=>{let a=b.current;if(a){let y=a.querySelectorAll("[data-zuude-hide-elements]"),p=a.querySelector("[data-zuude-video]");if(y){let R=null,H=3e3,v=!1,l=()=>{R&&(clearTimeout(R),R=null),R=setTimeout(()=>{v&&p&&!p.paused&&y.forEach(g=>{g.setAttribute("data-hidden","true")}),R=null},H)},f=()=>{v=!0,y.forEach(g=>{g.removeAttribute("data-hidden")}),l()},w=()=>{v=!1,R&&(clearTimeout(R),R=null),p&&!p.paused&&y.forEach(g=>{g.setAttribute("data-hidden","true")})},P=()=>{v&&(y.forEach(g=>{g.hasAttribute("data-hidden")&&g.removeAttribute("data-hidden")}),l())},k=()=>{v||y.forEach(g=>{g.setAttribute("data-hidden","true")})};return a.addEventListener("mouseenter",f),a.addEventListener("mouseleave",w),a.addEventListener("mousemove",P),p.addEventListener("pause",f),p.addEventListener("play",k),()=>{R&&clearTimeout(R),a.removeEventListener("mouseenter",f),a.removeEventListener("mouseleave",w),a.removeEventListener("mousemove",P),p.removeEventListener("pause",f),p.removeEventListener("play",k)}}}},[]),N(()=>{if(E){let a=y=>{var p;(p=b.current)!=null&&p.contains(y.target)||u(!1)};return document.addEventListener("click",a),()=>{document.removeEventListener("click",a)}}},[E]),K(W.Provider,{value:{videoRef:i,setVideoRef:o,config:{clickToPlay:!0,...r},error:s,setError:c,isFocused:E,setIsFocused:u},children:K("div",{ref:b,"data-zuude-video-wrapper":!0,onClick:()=>u(!0),...e,children:n})})}),m=()=>{let n=ee(W);if(!n)throw new Error("useVideo must be used within a VideoProvider");return n};import{forwardRef as re,useCallback as oe,useEffect as J,useRef as j}from"react";var G=()=>{let{videoRef:n}=m(),{seekForward:r,seekBackward:t}=x(n),{togglePlay:e}=A(n),{toggleMute:i}=S(n),{toggleFullscreen:o}=I(n),{togglePictureInPicture:s}=O(n);return M("ArrowRight",()=>{r()}),M("ArrowLeft",()=>{t()}),M(" ",()=>{e()}),M("m",()=>{i()}),M("f",()=>{o()}),M("p",()=>{s()}),null};import{Fragment as ie,jsx as Q,jsxs as se}from"react/jsx-runtime";var X=re(({src:n,autoPlay:r,muteFallback:t,controls:e,preload:i="metadata",autoPlayOnVisible:o,ranges:s,...c},E)=>{let{videoRef:u,setVideoRef:b,config:a,setError:y,error:p,isFocused:R}=m(),H=j(null),v=j(!1),l=j(null),f=j(null),w=s&&s.length>=2&&typeof s[0]=="number"&&typeof s[1]=="number"&&s[0]>=0&&s[1]>s[0]&&isFinite(s[0])&&isFinite(s[1]),P=w?s[0]:void 0,k=w?s[1]:void 0;J(()=>{let L=H.current,d=E;return d?b(d):L&&b({current:L}),()=>{v.current=!1,l.current!==null&&(cancelAnimationFrame(l.current),l.current=null),f.current!==null&&(clearTimeout(f.current),f.current=null)}},[n,E,b]),J(()=>()=>{l.current!==null&&(cancelAnimationFrame(l.current),l.current=null),f.current!==null&&(clearTimeout(f.current),f.current=null)},[]),q(u,r==="force"&&c.muted===void 0,y),z(u,typeof o=="number"?o:o?void 0:.5,!!o);let g=oe(()=>{var L,d,F;(L=u==null?void 0:u.current)!=null&&L.paused?(d=u.current)==null||d.play():(F=u==null?void 0:u.current)==null||F.pause()},[u]);return se(ie,{children:[Q("video",{ref:E||H,"data-zuude-video":!0,src:n,onClick:a!=null&&a.clickToPlay?g:void 0,autoPlay:r==="force"?!0:r,preload:i,playsInline:!0,onCanPlay:L=>{var F;let d=L.currentTarget;if(w&&P!==void 0&&k!==void 0&&d.paused){let V=d.currentTime;(V<P||V>k)&&(d.currentTime=P)}(F=c.onCanPlay)==null||F.call(c,L)},onSeeked:L=>{var F;let d=L.currentTarget;if(w&&P!==void 0&&k!==void 0&&d.paused){let V=d.currentTime;if((V<P||V>k)&&Math.abs(V-P)>.01){v.current=!0,d.currentTime=P,l.current!==null&&cancelAnimationFrame(l.current),l.current=requestAnimationFrame(()=>{v.current=!1,l.current=null});return}}v.current=!1,(F=c.onSeeked)==null||F.call(c,L)},onTimeUpdate:L=>{var F;let d=L.currentTarget;if(w&&P!==void 0&&k!==void 0&&!v.current){let V=d.currentTime;!d.paused&&V>=k?(v.current=!0,d.currentTime=P,f.current!==null&&clearTimeout(f.current),l.current=requestAnimationFrame(()=>{f.current=setTimeout(()=>{v.current&&(v.current=!1),f.current=null},100),l.current=null})):d.paused&&(V<P||V>k)&&(Math.abs(V-P)>.01||V>k)&&(v.current=!0,d.currentTime=P,l.current!==null&&cancelAnimationFrame(l.current),f.current!==null&&clearTimeout(f.current),l.current=requestAnimationFrame(()=>{v.current=!1,l.current=null}))}(F=c.onTimeUpdate)==null||F.call(c,L)},...c}),e&&R&&Q(G,{}),p==="NotAllowedError"&&typeof t=="function"&&t(()=>{u!=null&&u.current&&(u.current.muted=!u.current.muted),y(null)})]})});X.displayName="Video";import T,{useRef as ue}from"react";import{Slot as C}from"@radix-ui/react-slot";import Y from"react";var Z=n=>{let[r,t]=Y.useState(!1);return Y.useEffect(()=>{if(!(n!=null&&n.current))return;let e=n.current,i=()=>{t(!0)},o=()=>{},s=()=>{},c=()=>{t(!1)},E=()=>{t(!1)},u=()=>{t(!0)},b=()=>{t(!1)},a=()=>{t(!1)},y=()=>{t(!1)},p=()=>{};return e.addEventListener("loadstart",i),e.addEventListener("loadedmetadata",o),e.addEventListener("loadeddata",s),e.addEventListener("canplay",c),e.addEventListener("canplaythrough",E),e.addEventListener("waiting",u),e.addEventListener("playing",b),e.addEventListener("error",a),e.addEventListener("abort",y),e.addEventListener("suspend",p),e.readyState>=2&&t(!1),()=>{e.removeEventListener("loadstart",i),e.removeEventListener("loadedmetadata",o),e.removeEventListener("loadeddata",s),e.removeEventListener("canplay",c),e.removeEventListener("canplaythrough",E),e.removeEventListener("waiting",u),e.removeEventListener("playing",b),e.removeEventListener("error",a),e.removeEventListener("abort",y),e.removeEventListener("suspend",p)}},[n]),{isLoading:r}};import{jsx as h}from"react/jsx-runtime";var Ue=T.memo(({children:n,asChild:r,...t})=>h("div",{"data-zuude-hide-elements":!0,...t,children:n})),Be=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{play:o}=A(i);return h(e,{...t,onClick:o,children:n})}),Ke=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{pause:o}=A(i);return h(e,{...t,onClick:o,children:n})}),We=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{mute:o}=S(i);return h(e,{...t,onClick:o,children:n})}),Ge=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{unmute:o}=S(i);return h(e,{...t,onClick:o,children:n})}),Je=T.memo(({children:n,asChild:r,value:t,onClick:e,...i})=>{let o=r?C:"button",{videoRef:s}=m(),{speed:c,onChangeSpeed:E}=U(s);return h(o,{...i,value:t,onClick:()=>{E(t),e==null||e()},children:n})}),Qe=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{seekForward:o}=x(i,10);return h(e,{...t,onClick:o,children:n})}),Xe=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{seekBackward:o}=x(i,10);return h(e,{...t,onClick:o,children:n})}),Ye=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{toggleFullscreen:o}=I(i);return h(e,{...t,onClick:o,children:n})}),Ze=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{toggleFullscreen:o}=I(i);return h(e,{...t,onClick:o,children:n})}),_e=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{togglePictureInPicture:o}=O(i);return h(e,{...t,onClick:o,children:n})}),$e=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"button",{videoRef:i}=m(),{downloadDirect:o}=B(i);return h(e,{...t,onClick:()=>o(),children:n})}),et=T.memo(({children:n,asChild:r,...t})=>{let e=r?C:"div",{videoRef:i}=m(),{isLoading:o}=Z(i);return h(e,{...t,style:{...t.style,pointerEvents:"none"},"data-loading":o,children:n})}),tt=({...n})=>{let{videoRef:r}=m(),t=ue(null);return T.useEffect(()=>{let e=r==null?void 0:r.current;if(t.current&&e){let i=0,o=!1,s=null,c=()=>{s&&clearInterval(s),s=setInterval(()=>{i=e.currentTime,t.current&&(t.current.currentTime=i)},100)},E=()=>{s&&(clearInterval(s),s=null)},u=()=>{o=!0,c()},b=()=>{o=!1,E()};return e.addEventListener("play",u),e.addEventListener("pause",b),()=>{E(),e.removeEventListener("play",u),e.removeEventListener("pause",b)}}},[r==null?void 0:r.current]),r!=null&&r.current?h("div",{...n,style:{...n.style,position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none"},children:h("video",{ref:t,src:r.current.src,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"cover"}})}):null};export{Ue as Controls,$e as Download,Ze as ExitFullscreen,Ye as Fullscreen,et as Loading,We as Mute,Ke as Pause,_e as PictureInPicture,Be as Play,Xe as SeekBackward,Qe as SeekForward,tt as Shadow,Je as Speed,Ge as Unmute,X as Video,ne as VideoProvider,m as useVideo};
1
+ "use client";import{a as q,b as w,c as x,d as A,e as S,f as I,g as O,h as z,j as U,p as B}from"./chunk-XV6ODTKT.js";import _,{createContext as $,useContext as ee,useEffect as N,useRef as te,useState as D}from"react";import{jsx as K}from"react/jsx-runtime";var W=$(null),ne=_.memo(({children:n,config:r,onError:t,...e})=>{let[i,o]=D({current:null}),[s,a]=D(null),[h,u]=D(!1),R=te(null);return N(()=>{t==null||t(s)},[s]),N(()=>{let d=R.current;if(d){let L=d.querySelectorAll("[data-zuude-hide-elements]"),E=d.querySelector("[data-zuude-video]");if(L){let g=null,H=3e3,P=!1,l=()=>{g&&(clearTimeout(g),g=null),g=setTimeout(()=>{P&&E&&!E.paused&&L.forEach(C=>{C.setAttribute("data-hidden","true")}),g=null},H)},f=()=>{P=!0,L.forEach(C=>{C.removeAttribute("data-hidden")}),l()},M=()=>{P=!1,g&&(clearTimeout(g),g=null),E&&!E.paused&&L.forEach(C=>{C.setAttribute("data-hidden","true")})},v=()=>{P&&(L.forEach(C=>{C.hasAttribute("data-hidden")&&C.removeAttribute("data-hidden")}),l())},V=()=>{P||L.forEach(C=>{C.setAttribute("data-hidden","true")})};return d.addEventListener("mouseenter",f),d.addEventListener("mouseleave",M),d.addEventListener("mousemove",v),E.addEventListener("pause",f),E.addEventListener("play",V),()=>{g&&clearTimeout(g),d.removeEventListener("mouseenter",f),d.removeEventListener("mouseleave",M),d.removeEventListener("mousemove",v),E.removeEventListener("pause",f),E.removeEventListener("play",V)}}}},[]),N(()=>{if(h){let d=L=>{var E;(E=R.current)!=null&&E.contains(L.target)||u(!1)};return document.addEventListener("click",d),()=>{document.removeEventListener("click",d)}}},[h]),K(W.Provider,{value:{videoRef:i,setVideoRef:o,config:{clickToPlay:!0,...r},error:s,setError:a,isFocused:h,setIsFocused:u},children:K("div",{ref:R,"data-zuude-video-wrapper":!0,onClick:()=>u(!0),...e,children:n})})}),m=()=>{let n=ee(W);if(!n)throw new Error("useVideo must be used within a VideoProvider");return n};import{forwardRef as re,useCallback as oe,useEffect as J,useRef as j}from"react";var G=()=>{let{videoRef:n}=m(),{seekForward:r,seekBackward:t}=x(n),{togglePlay:e}=A(n),{toggleMute:i}=S(n),{toggleFullscreen:o}=I(n),{togglePictureInPicture:s}=O(n);return w("ArrowRight",()=>{r()}),w("ArrowLeft",()=>{t()}),w(" ",()=>{e()}),w("m",()=>{i()}),w("f",()=>{o()}),w("p",()=>{s()}),null};import{Fragment as ie,jsx as Q,jsxs as se}from"react/jsx-runtime";var X=re(({src:n,autoPlay:r,muteFallback:t,controls:e,preload:i="metadata",autoPlayOnVisible:o,ranges:s,...a},h)=>{let{videoRef:u,setVideoRef:R,config:d,setError:L,error:E,isFocused:g}=m(),H=j(null),P=j(!1),l=j(null),f=j(null),M=s&&s.length>=2&&typeof s[0]=="number"&&typeof s[1]=="number"&&s[0]>=0&&s[1]>s[0]&&isFinite(s[0])&&isFinite(s[1]),v=M?s[0]:void 0,V=M?s[1]:void 0;J(()=>{let p=H.current,c=h;return c?R(c):p&&R({current:p}),()=>{P.current=!1,l.current!==null&&(cancelAnimationFrame(l.current),l.current=null),f.current!==null&&(clearTimeout(f.current),f.current=null)}},[n,h,R]),J(()=>()=>{l.current!==null&&(cancelAnimationFrame(l.current),l.current=null),f.current!==null&&(clearTimeout(f.current),f.current=null)},[]),q(u,r==="force"&&a.muted===void 0,L),z(u,typeof o=="number"?o:o?void 0:.5,!!o);let C=oe(()=>{var p,c,T;(p=u==null?void 0:u.current)!=null&&p.paused?(c=u.current)==null||c.play():(T=u==null?void 0:u.current)==null||T.pause()},[u]);return se(ie,{children:[Q("video",{ref:h||H,"data-zuude-video":!0,src:n,onClick:d!=null&&d.clickToPlay?C:void 0,autoPlay:r==="force"?!0:r,preload:i,playsInline:!0,onLoadedMetadata:p=>{var T;let c=p.currentTarget;M&&v!==void 0&&V!==void 0&&(c.currentTime=v),(T=a.onLoadedMetadata)==null||T.call(a,p)},onCanPlay:p=>{var T;let c=p.currentTarget;if(M&&v!==void 0&&V!==void 0){let k=c.currentTime;(k<v||k>V)&&(c.currentTime=v)}(T=a.onCanPlay)==null||T.call(a,p)},onSeeked:p=>{var T;let c=p.currentTarget;if(M&&v!==void 0&&V!==void 0&&c.paused){let k=c.currentTime;if((k<v||k>V)&&Math.abs(k-v)>.01){P.current=!0,c.currentTime=v,l.current!==null&&cancelAnimationFrame(l.current),l.current=requestAnimationFrame(()=>{P.current=!1,l.current=null});return}}P.current=!1,(T=a.onSeeked)==null||T.call(a,p)},onTimeUpdate:p=>{var T;let c=p.currentTarget;if(M&&v!==void 0&&V!==void 0&&!P.current){let k=c.currentTime;!c.paused&&k>=V?(P.current=!0,c.currentTime=v,f.current!==null&&clearTimeout(f.current),l.current=requestAnimationFrame(()=>{f.current=setTimeout(()=>{P.current&&(P.current=!1),f.current=null},100),l.current=null})):c.paused&&(k<v||k>V)&&(Math.abs(k-v)>.01||k>V)&&(P.current=!0,c.currentTime=v,l.current!==null&&cancelAnimationFrame(l.current),f.current!==null&&clearTimeout(f.current),l.current=requestAnimationFrame(()=>{P.current=!1,l.current=null}))}(T=a.onTimeUpdate)==null||T.call(a,p)},...a}),e&&g&&Q(G,{}),E==="NotAllowedError"&&typeof t=="function"&&t(()=>{u!=null&&u.current&&(u.current.muted=!u.current.muted),L(null)})]})});X.displayName="Video";import b,{useRef as ue}from"react";import{Slot as F}from"@radix-ui/react-slot";import Y from"react";var Z=n=>{let[r,t]=Y.useState(!1);return Y.useEffect(()=>{if(!(n!=null&&n.current))return;let e=n.current,i=()=>{t(!0)},o=()=>{},s=()=>{},a=()=>{t(!1)},h=()=>{t(!1)},u=()=>{t(!0)},R=()=>{t(!1)},d=()=>{t(!1)},L=()=>{t(!1)},E=()=>{};return e.addEventListener("loadstart",i),e.addEventListener("loadedmetadata",o),e.addEventListener("loadeddata",s),e.addEventListener("canplay",a),e.addEventListener("canplaythrough",h),e.addEventListener("waiting",u),e.addEventListener("playing",R),e.addEventListener("error",d),e.addEventListener("abort",L),e.addEventListener("suspend",E),e.readyState>=2&&t(!1),()=>{e.removeEventListener("loadstart",i),e.removeEventListener("loadedmetadata",o),e.removeEventListener("loadeddata",s),e.removeEventListener("canplay",a),e.removeEventListener("canplaythrough",h),e.removeEventListener("waiting",u),e.removeEventListener("playing",R),e.removeEventListener("error",d),e.removeEventListener("abort",L),e.removeEventListener("suspend",E)}},[n]),{isLoading:r}};import{jsx as y}from"react/jsx-runtime";var Ue=b.memo(({children:n,asChild:r,...t})=>y("div",{"data-zuude-hide-elements":!0,...t,children:n})),Be=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{play:o}=A(i);return y(e,{...t,onClick:o,children:n})}),Ke=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{pause:o}=A(i);return y(e,{...t,onClick:o,children:n})}),We=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{mute:o}=S(i);return y(e,{...t,onClick:o,children:n})}),Ge=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{unmute:o}=S(i);return y(e,{...t,onClick:o,children:n})}),Je=b.memo(({children:n,asChild:r,value:t,onClick:e,...i})=>{let o=r?F:"button",{videoRef:s}=m(),{speed:a,onChangeSpeed:h}=U(s);return y(o,{...i,value:t,onClick:()=>{h(t),e==null||e()},children:n})}),Qe=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{seekForward:o}=x(i,10);return y(e,{...t,onClick:o,children:n})}),Xe=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{seekBackward:o}=x(i,10);return y(e,{...t,onClick:o,children:n})}),Ye=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{toggleFullscreen:o}=I(i);return y(e,{...t,onClick:o,children:n})}),Ze=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{toggleFullscreen:o}=I(i);return y(e,{...t,onClick:o,children:n})}),_e=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{togglePictureInPicture:o}=O(i);return y(e,{...t,onClick:o,children:n})}),$e=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"button",{videoRef:i}=m(),{downloadDirect:o}=B(i);return y(e,{...t,onClick:()=>o(),children:n})}),et=b.memo(({children:n,asChild:r,...t})=>{let e=r?F:"div",{videoRef:i}=m(),{isLoading:o}=Z(i);return y(e,{...t,style:{...t.style,pointerEvents:"none"},"data-loading":o,children:n})}),tt=({...n})=>{let{videoRef:r}=m(),t=ue(null);return b.useEffect(()=>{let e=r==null?void 0:r.current;if(t.current&&e){let i=0,o=!1,s=null,a=()=>{s&&clearInterval(s),s=setInterval(()=>{i=e.currentTime,t.current&&(t.current.currentTime=i)},100)},h=()=>{s&&(clearInterval(s),s=null)},u=()=>{o=!0,a()},R=()=>{o=!1,h()};return e.addEventListener("play",u),e.addEventListener("pause",R),()=>{h(),e.removeEventListener("play",u),e.removeEventListener("pause",R)}}},[r==null?void 0:r.current]),r!=null&&r.current?y("div",{...n,style:{...n.style,position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none"},children:y("video",{ref:t,src:r.current.src,muted:!0,playsInline:!0,style:{width:"100%",height:"100%",objectFit:"cover"}})}):null};export{Ue as Controls,$e as Download,Ze as ExitFullscreen,Ye as Fullscreen,et as Loading,We as Mute,Ke as Pause,_e as PictureInPicture,Be as Play,Xe as SeekBackward,Qe as SeekForward,tt as Shadow,Je as Speed,Ge as Unmute,X as Video,ne as VideoProvider,m as useVideo};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/wrapper.tsx","../src/video.tsx","../src/keyboard.tsx","../src/components.tsx","../src/hooks/use-loading.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, {\n forwardRef,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\nimport { useAutoplayOnVisible } from \"./hooks\";\n\ninterface Props\n extends Omit<React.ComponentProps<\"video\">, \"autoPlay\" | \"preload\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n muteFallback?: (onMute: () => void) => React.ReactNode;\n autoPlayOnVisible?: boolean | number;\n ranges?: number[];\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n (\n {\n src,\n autoPlay,\n muteFallback,\n controls,\n preload = \"metadata\",\n autoPlayOnVisible,\n ranges,\n ...props\n },\n ref\n ) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n const isAdjustingRef = useRef(false);\n const rafIdRef = useRef<number | null>(null);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Validate ranges: ensure they're valid and start < end\n const isValidRange =\n ranges &&\n ranges.length >= 2 &&\n typeof ranges[0] === \"number\" &&\n typeof ranges[1] === \"number\" &&\n ranges[0] >= 0 &&\n ranges[1] > ranges[0] &&\n isFinite(ranges[0]) &&\n isFinite(ranges[1]);\n\n // Safely get range values (only use when isValidRange is true)\n const rangeStart = isValidRange ? ranges[0] : undefined;\n const rangeEnd = isValidRange ? ranges[1] : undefined;\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n\n // Safari: Reset adjustment flags when src changes to prevent stale state\n return () => {\n isAdjustingRef.current = false;\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, [src, ref, setVideoRef]);\n\n // Cleanup requestAnimationFrame and setTimeout on unmount (critical for Safari)\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, []);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n useAutoplayOnVisible(\n videoRef,\n typeof autoPlayOnVisible === \"number\"\n ? autoPlayOnVisible\n : !autoPlayOnVisible\n ? 0.5\n : undefined,\n !!autoPlayOnVisible\n );\n\n const onPlay = useCallback(() => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n }, [videoRef]);\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n preload={preload}\n playsInline\n onCanPlay={(e) => {\n // Set initial position when video is ready to play (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n // Only adjust if we're outside the range to avoid unnecessary seeks\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n video.currentTime = rangeStart;\n }\n }\n props.onCanPlay?.(e);\n }}\n onSeeked={(e) => {\n // Adjust position after user seeks (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n // Only seek if significantly outside range to avoid infinite loop\n if (Math.abs(currentTime - rangeStart) > 0.01) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay in case onSeeked doesn't fire again\n // Cleanup existing RAF before setting new one (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n return; // Exit early to prevent calling props.onSeeked twice\n }\n }\n }\n isAdjustingRef.current = false;\n props.onSeeked?.(e);\n }}\n onTimeUpdate={(e) => {\n const video = e.currentTarget;\n\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n !isAdjustingRef.current\n ) {\n const currentTime = video.currentTime;\n\n // During playback: loop back when reaching or exceeding the end boundary\n if (!video.paused && currentTime >= rangeEnd) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after seek completes (onSeeked will handle this)\n // But add a fallback timeout in case onSeeked doesn't fire\n // Cleanup existing timeout before setting new one (Safari memory safety)\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n timeoutIdRef.current = setTimeout(() => {\n if (isAdjustingRef.current) {\n isAdjustingRef.current = false;\n }\n timeoutIdRef.current = null;\n }, 100);\n rafIdRef.current = null;\n });\n }\n // When paused: ensure we're within range\n else if (\n video.paused &&\n (currentTime < rangeStart || currentTime > rangeEnd)\n ) {\n // Only adjust if significantly outside range to avoid constant micro-adjustments\n if (\n Math.abs(currentTime - rangeStart) > 0.01 ||\n currentTime > rangeEnd\n ) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay since we're paused\n // Cleanup existing RAF and timeout before setting new ones (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n }\n }\n }\n\n props.onTimeUpdate?.(e);\n }}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React, { RefObject, useRef } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useCurrentTime } from \"./hooks/use-current-time\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useDownload } from \"./hooks/use-download\";\nimport { useSpeed } from \"./hooks\";\nimport { useLoading } from \"./hooks/use-loading\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\ninterface SpeedProps extends Props {\n value: number;\n onClick?: () => void;\n}\n\nconst Speed = React.memo(\n ({ children, asChild, value, onClick, ...props }: SpeedProps) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { speed, onChangeSpeed } = useSpeed(\n videoRef as RefObject<HTMLVideoElement>\n );\n\n return (\n <Element\n {...props}\n value={value}\n onClick={() => {\n onChangeSpeed(value);\n onClick?.();\n }}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst PictureInPicture = React.memo(\n ({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n return (\n <Element {...props} onClick={togglePictureInPicture}>\n {children}\n </Element>\n );\n }\n);\n\nconst Download = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { downloadDirect } = useDownload(videoRef);\n\n return (\n <Element {...props} onClick={() => downloadDirect()}>\n {children}\n </Element>\n );\n});\n\ninterface LoadingProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Loading = React.memo(({ children, asChild, ...props }: LoadingProps) => {\n const Element = asChild ? Slot : \"div\";\n const { videoRef } = useVideo();\n\n const { isLoading } = useLoading(videoRef);\n\n return (\n <Element\n {...props}\n style={{ ...props.style, pointerEvents: \"none\" }}\n data-loading={isLoading}\n >\n {children}\n </Element>\n );\n});\n\ninterface ShadowProps extends React.ComponentProps<\"div\"> {}\n\nconst Shadow = ({ ...props }: ShadowProps) => {\n const { videoRef } = useVideo();\n\n const shadowVideoRef = useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n const video = videoRef?.current;\n if (shadowVideoRef.current && video) {\n let currentTime = 0;\n let isPlaying = false;\n let interval: ReturnType<typeof setInterval> | null = null;\n\n const startInterval = () => {\n if (interval) clearInterval(interval);\n interval = setInterval(() => {\n currentTime = video.currentTime;\n if (shadowVideoRef.current) {\n shadowVideoRef.current.currentTime = currentTime;\n }\n }, 100);\n };\n\n const stopInterval = () => {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n };\n\n const handlePlay = () => {\n isPlaying = true;\n startInterval();\n };\n\n const handlePause = () => {\n isPlaying = false;\n stopInterval();\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n stopInterval();\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n if (!videoRef?.current) return null;\n\n return (\n <div\n {...props}\n style={{\n ...props.style,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <video\n ref={shadowVideoRef}\n src={videoRef.current.src}\n muted\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n }}\n />\n </div>\n );\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n Speed,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n PictureInPicture,\n Download,\n Loading,\n Shadow,\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useLoading = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n const handleLoadStart = () => {\n setIsLoading(true);\n };\n\n const handleLoadedMetadata = () => {\n // Metadata loaded but video might not be ready to play yet\n // Keep loading true until canplay\n };\n\n const handleLoadedData = () => {\n // First frame loaded, but might still be buffering\n // Keep loading true until canplay\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n };\n\n const handleWaiting = () => {\n // Video is waiting for data (buffering)\n setIsLoading(true);\n };\n\n const handlePlaying = () => {\n // Video is playing, so it's not loading anymore\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const handleAbort = () => {\n setIsLoading(false);\n };\n\n const handleSuspend = () => {\n // Loading suspended (e.g., user paused)\n // Don't change loading state here\n };\n\n // Add event listeners\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"abort\", handleAbort);\n video.addEventListener(\"suspend\", handleSuspend);\n\n // Check initial state\n if (video.readyState >= 2) {\n setIsLoading(false);\n }\n\n return () => {\n // Remove event listeners\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"abort\", handleAbort);\n video.removeEventListener(\"suspend\", handleSuspend);\n };\n }, [videoRef]);\n\n return { isLoading };\n};\n"],"mappings":"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","names":["React","createContext","useContext","useEffect","useRef","useState","jsx","VideoContext","VideoProvider","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","forwardRef","useCallback","useEffect","useRef","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","Fragment","jsx","jsxs","Video","forwardRef","src","autoPlay","muteFallback","controls","preload","autoPlayOnVisible","ranges","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","useRef","isAdjustingRef","rafIdRef","timeoutIdRef","isValidRange","rangeStart","rangeEnd","useEffect","video","thirdPartyRef","useAutoplayByForce","useAutoplayOnVisible","onPlay","useCallback","_a","_b","_c","e","currentTime","Keyboards","React","useRef","Slot","React","useLoading","videoRef","isLoading","setIsLoading","video","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handleError","handleAbort","handleSuspend","jsx","Controls","React","children","asChild","props","Play","Element","Slot","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","Speed","value","onClick","speed","onChangeSpeed","useSpeed","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","PictureInPicture","togglePictureInPicture","usePictureInPicture","Download","downloadDirect","useDownload","Loading","isLoading","useLoading","Shadow","shadowVideoRef","useRef","video","currentTime","isPlaying","interval","startInterval","stopInterval","handlePlay","handlePause"]}
1
+ {"version":3,"sources":["../src/wrapper.tsx","../src/video.tsx","../src/keyboard.tsx","../src/components.tsx","../src/hooks/use-loading.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { VideoRef } from \"./types\";\n\ninterface VideoConfig {\n config?: Partial<{\n clickToPlay: boolean;\n }>;\n}\n\ninterface VideoContextType extends VideoConfig {\n videoRef: VideoRef;\n setVideoRef: (video: VideoRef) => void;\n error: string | null;\n setError: (error: string | null) => void;\n isFocused: boolean;\n setIsFocused: (isFocused: boolean) => void;\n}\n\nexport const VideoContext = createContext<VideoContextType | null>(null);\n\ntype VideoProviderProps = Omit<React.ComponentProps<\"div\">, \"onError\"> &\n VideoConfig & {\n children: React.ReactNode;\n onError?: (error: string | null) => void;\n };\n\nexport const VideoProvider = React.memo(\n ({ children, config, onError, ...props }: VideoProviderProps) => {\n const [videoRef, setVideoRef] = useState<VideoRef>({ current: null });\n const [error, setError] = useState<string | null>(null);\n const [isFocused, setIsFocused] = useState(false);\n\n const videoWrapperRef = useRef<HTMLDivElement>(null);\n\n // Sending error to user if it exists\n useEffect(() => {\n onError?.(error);\n }, [error]);\n\n useEffect(() => {\n const videoWrapper = videoWrapperRef.current;\n if (videoWrapper) {\n const controls = videoWrapper.querySelectorAll(\n \"[data-zuude-hide-elements]\"\n );\n const video = videoWrapper.querySelector(\n \"[data-zuude-video]\"\n ) as HTMLVideoElement;\n\n if (controls) {\n let hideTimeout: ReturnType<typeof setTimeout> | null = null;\n const hideDelay = 3000; // 3 seconds delay\n let isMouseOver = false;\n\n const resetTimer = () => {\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n\n // Start new timer to hide controls after delay\n hideTimeout = setTimeout(() => {\n if (isMouseOver) {\n // Check if video is paused - don't hide controls if paused\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n }\n hideTimeout = null;\n }, hideDelay);\n };\n\n const showControls = () => {\n isMouseOver = true;\n controls.forEach((control) => {\n control.removeAttribute(\"data-hidden\");\n });\n resetTimer();\n };\n\n const hideControls = () => {\n isMouseOver = false;\n // Clear any pending hide timeout\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n hideTimeout = null;\n }\n // Hide controls immediately when mouse leaves\n if (video && !video.paused) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n const handleMouseMove = () => {\n if (isMouseOver) {\n // If controls are hidden, show them\n controls.forEach((control) => {\n if (control.hasAttribute(\"data-hidden\")) {\n control.removeAttribute(\"data-hidden\");\n }\n });\n resetTimer();\n }\n };\n\n const handlePlay = () => {\n // Hide controls when video starts playing (autoplay)\n if (!isMouseOver) {\n controls.forEach((control) => {\n control.setAttribute(\"data-hidden\", \"true\");\n });\n }\n };\n\n videoWrapper.addEventListener(\"mouseenter\", showControls);\n videoWrapper.addEventListener(\"mouseleave\", hideControls);\n videoWrapper.addEventListener(\"mousemove\", handleMouseMove);\n video.addEventListener(\"pause\", showControls);\n video.addEventListener(\"play\", handlePlay);\n\n // Cleanup function\n return () => {\n if (hideTimeout) {\n clearTimeout(hideTimeout);\n }\n videoWrapper.removeEventListener(\"mouseenter\", showControls);\n videoWrapper.removeEventListener(\"mouseleave\", hideControls);\n videoWrapper.removeEventListener(\"mousemove\", handleMouseMove);\n video.removeEventListener(\"pause\", showControls);\n video.removeEventListener(\"play\", handlePlay);\n };\n }\n }\n }, []);\n\n useEffect(() => {\n if (isFocused) {\n const handleClick = (event: MouseEvent) => {\n if (!videoWrapperRef.current?.contains(event.target as Node)) {\n setIsFocused(false);\n }\n };\n document.addEventListener(\"click\", handleClick);\n\n return () => {\n document.removeEventListener(\"click\", handleClick);\n };\n }\n }, [isFocused]);\n\n return (\n <VideoContext.Provider\n value={{\n videoRef,\n setVideoRef,\n config: { clickToPlay: true, ...config },\n error,\n setError,\n isFocused,\n setIsFocused,\n }}\n >\n <div\n ref={videoWrapperRef}\n data-zuude-video-wrapper\n onClick={() => setIsFocused(true)}\n {...props}\n >\n {children}\n </div>\n </VideoContext.Provider>\n );\n }\n);\n\nexport const useVideo = () => {\n const context = useContext(VideoContext);\n if (!context) {\n throw new Error(\"useVideo must be used within a VideoProvider\");\n }\n return context;\n};\n","import React, {\n forwardRef,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { useVideo } from \"./wrapper\";\nimport { VideoAutoplay } from \"./types\";\nimport { useAutoplayByForce } from \"./hooks/use-autoplay-by-force\";\nimport { Keyboards } from \"./keyboard\";\nimport { useAutoplayOnVisible } from \"./hooks\";\n\ninterface Props\n extends Omit<React.ComponentProps<\"video\">, \"autoPlay\" | \"preload\"> {\n src: string;\n autoPlay?: VideoAutoplay;\n controls?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n muteFallback?: (onMute: () => void) => React.ReactNode;\n autoPlayOnVisible?: boolean | number;\n ranges?: number[];\n}\n\nexport const Video = forwardRef<HTMLVideoElement, Props>(\n (\n {\n src,\n autoPlay,\n muteFallback,\n controls,\n preload = \"metadata\",\n autoPlayOnVisible,\n ranges,\n ...props\n },\n ref\n ) => {\n const { videoRef, setVideoRef, config, setError, error, isFocused } =\n useVideo();\n\n const refVideo = useRef<HTMLVideoElement>(null);\n const isAdjustingRef = useRef(false);\n const rafIdRef = useRef<number | null>(null);\n const timeoutIdRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Validate ranges: ensure they're valid and start < end\n const isValidRange =\n ranges &&\n ranges.length >= 2 &&\n typeof ranges[0] === \"number\" &&\n typeof ranges[1] === \"number\" &&\n ranges[0] >= 0 &&\n ranges[1] > ranges[0] &&\n isFinite(ranges[0]) &&\n isFinite(ranges[1]);\n\n // Safely get range values (only use when isValidRange is true)\n const rangeStart = isValidRange ? ranges[0] : undefined;\n const rangeEnd = isValidRange ? ranges[1] : undefined;\n\n useEffect(() => {\n const video = refVideo.current;\n const thirdPartyRef = ref;\n\n if (thirdPartyRef) {\n setVideoRef(thirdPartyRef as RefObject<HTMLVideoElement>);\n } else {\n if (video) {\n setVideoRef({ current: video });\n }\n }\n\n // Safari: Reset adjustment flags when src changes to prevent stale state\n return () => {\n isAdjustingRef.current = false;\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, [src, ref, setVideoRef]);\n\n // Cleanup requestAnimationFrame and setTimeout on unmount (critical for Safari)\n useEffect(() => {\n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n rafIdRef.current = null;\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n timeoutIdRef.current = null;\n }\n };\n }, []);\n\n useAutoplayByForce(\n videoRef,\n autoPlay === \"force\" && props.muted === undefined,\n setError\n );\n\n useAutoplayOnVisible(\n videoRef,\n typeof autoPlayOnVisible === \"number\"\n ? autoPlayOnVisible\n : !autoPlayOnVisible\n ? 0.5\n : undefined,\n !!autoPlayOnVisible\n );\n\n const onPlay = useCallback(() => {\n if (videoRef?.current?.paused) {\n videoRef.current?.play();\n } else {\n videoRef?.current?.pause();\n }\n }, [videoRef]);\n\n return (\n <>\n <video\n ref={ref || refVideo}\n data-zuude-video\n src={src}\n onClick={config?.clickToPlay ? onPlay : undefined}\n autoPlay={autoPlay === \"force\" ? true : autoPlay}\n preload={preload}\n playsInline\n onLoadedMetadata={(e) => {\n // Set initial position as early as possible when metadata loads\n // This ensures video starts at rangeStart even with autoplay\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined\n ) {\n // Always set to rangeStart on initial load to ensure correct starting position\n video.currentTime = rangeStart;\n }\n props.onLoadedMetadata?.(e);\n }}\n onCanPlay={(e) => {\n // Ensure position is correct when video is ready to play\n // This is a backup in case onLoadedMetadata didn't set it correctly\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined\n ) {\n const currentTime = video.currentTime;\n // Only adjust if significantly outside range to avoid unnecessary seeks\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n video.currentTime = rangeStart;\n }\n }\n props.onCanPlay?.(e);\n }}\n onSeeked={(e) => {\n // Adjust position after user seeks (only if paused)\n const video = e.currentTarget;\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n video.paused\n ) {\n const currentTime = video.currentTime;\n if (currentTime < rangeStart || currentTime > rangeEnd) {\n // Only seek if significantly outside range to avoid infinite loop\n if (Math.abs(currentTime - rangeStart) > 0.01) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay in case onSeeked doesn't fire again\n // Cleanup existing RAF before setting new one (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n return; // Exit early to prevent calling props.onSeeked twice\n }\n }\n }\n isAdjustingRef.current = false;\n props.onSeeked?.(e);\n }}\n onTimeUpdate={(e) => {\n const video = e.currentTarget;\n\n if (\n isValidRange &&\n rangeStart !== undefined &&\n rangeEnd !== undefined &&\n !isAdjustingRef.current\n ) {\n const currentTime = video.currentTime;\n\n // During playback: loop back when reaching or exceeding the end boundary\n if (!video.paused && currentTime >= rangeEnd) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after seek completes (onSeeked will handle this)\n // But add a fallback timeout in case onSeeked doesn't fire\n // Cleanup existing timeout before setting new one (Safari memory safety)\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n timeoutIdRef.current = setTimeout(() => {\n if (isAdjustingRef.current) {\n isAdjustingRef.current = false;\n }\n timeoutIdRef.current = null;\n }, 100);\n rafIdRef.current = null;\n });\n }\n // When paused: ensure we're within range\n else if (\n video.paused &&\n (currentTime < rangeStart || currentTime > rangeEnd)\n ) {\n // Only adjust if significantly outside range to avoid constant micro-adjustments\n if (\n Math.abs(currentTime - rangeStart) > 0.01 ||\n currentTime > rangeEnd\n ) {\n isAdjustingRef.current = true;\n video.currentTime = rangeStart;\n // Reset flag after a brief delay since we're paused\n // Cleanup existing RAF and timeout before setting new ones (Safari memory safety)\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n if (timeoutIdRef.current !== null) {\n clearTimeout(timeoutIdRef.current);\n }\n rafIdRef.current = requestAnimationFrame(() => {\n isAdjustingRef.current = false;\n rafIdRef.current = null;\n });\n }\n }\n }\n\n props.onTimeUpdate?.(e);\n }}\n {...props}\n />\n\n {controls && isFocused && <Keyboards />}\n\n {error === \"NotAllowedError\" &&\n typeof muteFallback === \"function\" &&\n muteFallback(() => {\n if (videoRef?.current) {\n videoRef.current.muted = !videoRef.current.muted;\n }\n setError(null);\n })}\n </>\n );\n }\n);\n\nVideo.displayName = \"Video\";\n","import { useVideo } from \"./wrapper\";\nimport { useHotKeys } from \"./hooks/use-hot-keys\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\n\nexport const Keyboards = () => {\n const { videoRef } = useVideo();\n\n const { seekForward, seekBackward } = useSeek(videoRef);\n const { togglePlay } = usePlayPause(videoRef);\n const { toggleMute } = useMuteUnmute(videoRef);\n const { toggleFullscreen } = useFullscreen(videoRef);\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n useHotKeys(\"ArrowRight\", () => {\n seekForward();\n });\n useHotKeys(\"ArrowLeft\", () => {\n seekBackward();\n });\n useHotKeys(\" \", () => {\n togglePlay();\n });\n useHotKeys(\"m\", () => {\n toggleMute();\n });\n useHotKeys(\"f\", () => {\n toggleFullscreen();\n });\n useHotKeys(\"p\", () => {\n togglePictureInPicture();\n });\n\n return null;\n};\n","import React, { RefObject, useRef } from \"react\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { useVideo } from \"./wrapper\";\nimport { useFullscreen } from \"./hooks/use-fullscreen\";\nimport { useSeek } from \"./hooks/use-seek\";\nimport { useMuteUnmute } from \"./hooks/use-mute-unmute\";\nimport { usePlayPause } from \"./hooks/use-play-pause\";\nimport { useCurrentTime } from \"./hooks/use-current-time\";\nimport { usePictureInPicture } from \"./hooks/use-picture-in-picture\";\nimport { useDownload } from \"./hooks/use-download\";\nimport { useSpeed } from \"./hooks\";\nimport { useLoading } from \"./hooks/use-loading\";\n\ninterface ControlsProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Controls = React.memo(\n ({ children, asChild, ...props }: ControlsProps) => {\n return (\n <div data-zuude-hide-elements {...props}>\n {children}\n </div>\n );\n }\n);\n\ninterface Props extends React.ComponentProps<\"button\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Play = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { play } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={play}>\n {children}\n </Element>\n );\n});\n\nconst Pause = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { pause } = usePlayPause(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={pause}>\n {children}\n </Element>\n );\n});\n\nconst Mute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { mute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={mute}>\n {children}\n </Element>\n );\n});\n\nconst Unmute = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { unmute } = useMuteUnmute(videoRef as RefObject<HTMLVideoElement>);\n\n return (\n <Element {...props} onClick={unmute}>\n {children}\n </Element>\n );\n});\n\ninterface SpeedProps extends Props {\n value: number;\n onClick?: () => void;\n}\n\nconst Speed = React.memo(\n ({ children, asChild, value, onClick, ...props }: SpeedProps) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { speed, onChangeSpeed } = useSpeed(\n videoRef as RefObject<HTMLVideoElement>\n );\n\n return (\n <Element\n {...props}\n value={value}\n onClick={() => {\n onChangeSpeed(value);\n onClick?.();\n }}\n >\n {children}\n </Element>\n );\n }\n);\n\nconst SeekForward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekForward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekForward}>\n {children}\n </Element>\n );\n});\n\nconst SeekBackward = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { seekBackward } = useSeek(videoRef as RefObject<HTMLVideoElement>, 10);\n\n return (\n <Element {...props} onClick={seekBackward}>\n {children}\n </Element>\n );\n});\n\nconst Fullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst ExitFullscreen = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { toggleFullscreen } = useFullscreen(videoRef);\n\n return (\n <Element {...props} onClick={toggleFullscreen}>\n {children}\n </Element>\n );\n});\n\nconst PictureInPicture = React.memo(\n ({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { togglePictureInPicture } = usePictureInPicture(videoRef);\n\n return (\n <Element {...props} onClick={togglePictureInPicture}>\n {children}\n </Element>\n );\n }\n);\n\nconst Download = React.memo(({ children, asChild, ...props }: Props) => {\n const Element = asChild ? Slot : \"button\";\n const { videoRef } = useVideo();\n\n const { downloadDirect } = useDownload(videoRef);\n\n return (\n <Element {...props} onClick={() => downloadDirect()}>\n {children}\n </Element>\n );\n});\n\ninterface LoadingProps extends React.ComponentProps<\"div\"> {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst Loading = React.memo(({ children, asChild, ...props }: LoadingProps) => {\n const Element = asChild ? Slot : \"div\";\n const { videoRef } = useVideo();\n\n const { isLoading } = useLoading(videoRef);\n\n return (\n <Element\n {...props}\n style={{ ...props.style, pointerEvents: \"none\" }}\n data-loading={isLoading}\n >\n {children}\n </Element>\n );\n});\n\ninterface ShadowProps extends React.ComponentProps<\"div\"> {}\n\nconst Shadow = ({ ...props }: ShadowProps) => {\n const { videoRef } = useVideo();\n\n const shadowVideoRef = useRef<HTMLVideoElement>(null);\n\n React.useEffect(() => {\n const video = videoRef?.current;\n if (shadowVideoRef.current && video) {\n let currentTime = 0;\n let isPlaying = false;\n let interval: ReturnType<typeof setInterval> | null = null;\n\n const startInterval = () => {\n if (interval) clearInterval(interval);\n interval = setInterval(() => {\n currentTime = video.currentTime;\n if (shadowVideoRef.current) {\n shadowVideoRef.current.currentTime = currentTime;\n }\n }, 100);\n };\n\n const stopInterval = () => {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n };\n\n const handlePlay = () => {\n isPlaying = true;\n startInterval();\n };\n\n const handlePause = () => {\n isPlaying = false;\n stopInterval();\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n\n return () => {\n stopInterval();\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n };\n }\n }, [videoRef?.current]);\n\n if (!videoRef?.current) return null;\n\n return (\n <div\n {...props}\n style={{\n ...props.style,\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n }}\n >\n <video\n ref={shadowVideoRef}\n src={videoRef.current.src}\n muted\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n }}\n />\n </div>\n );\n};\n\nexport {\n Controls,\n Play,\n Pause,\n Mute,\n Unmute,\n Speed,\n SeekForward,\n SeekBackward,\n Fullscreen,\n ExitFullscreen,\n PictureInPicture,\n Download,\n Loading,\n Shadow,\n};\n","import React from \"react\";\nimport type { VideoRef } from \"../types\";\n\nexport const useLoading = (videoRef: VideoRef) => {\n const [isLoading, setIsLoading] = React.useState(false);\n\n React.useEffect(() => {\n if (!videoRef?.current) return;\n\n const video = videoRef.current;\n\n const handleLoadStart = () => {\n setIsLoading(true);\n };\n\n const handleLoadedMetadata = () => {\n // Metadata loaded but video might not be ready to play yet\n // Keep loading true until canplay\n };\n\n const handleLoadedData = () => {\n // First frame loaded, but might still be buffering\n // Keep loading true until canplay\n };\n\n const handleCanPlay = () => {\n setIsLoading(false);\n };\n\n const handleCanPlayThrough = () => {\n setIsLoading(false);\n };\n\n const handleWaiting = () => {\n // Video is waiting for data (buffering)\n setIsLoading(true);\n };\n\n const handlePlaying = () => {\n // Video is playing, so it's not loading anymore\n setIsLoading(false);\n };\n\n const handleError = () => {\n setIsLoading(false);\n };\n\n const handleAbort = () => {\n setIsLoading(false);\n };\n\n const handleSuspend = () => {\n // Loading suspended (e.g., user paused)\n // Don't change loading state here\n };\n\n // Add event listeners\n video.addEventListener(\"loadstart\", handleLoadStart);\n video.addEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.addEventListener(\"loadeddata\", handleLoadedData);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"playing\", handlePlaying);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"abort\", handleAbort);\n video.addEventListener(\"suspend\", handleSuspend);\n\n // Check initial state\n if (video.readyState >= 2) {\n setIsLoading(false);\n }\n\n return () => {\n // Remove event listeners\n video.removeEventListener(\"loadstart\", handleLoadStart);\n video.removeEventListener(\"loadedmetadata\", handleLoadedMetadata);\n video.removeEventListener(\"loadeddata\", handleLoadedData);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"canplaythrough\", handleCanPlayThrough);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"playing\", handlePlaying);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"abort\", handleAbort);\n video.removeEventListener(\"suspend\", handleSuspend);\n };\n }, [videoRef]);\n\n return { isLoading };\n};\n"],"mappings":"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","names":["React","createContext","useContext","useEffect","useRef","useState","jsx","VideoContext","VideoProvider","children","config","onError","props","videoRef","setVideoRef","error","setError","isFocused","setIsFocused","videoWrapperRef","videoWrapper","controls","video","hideTimeout","hideDelay","isMouseOver","resetTimer","control","showControls","hideControls","handleMouseMove","handlePlay","handleClick","event","_a","useVideo","context","forwardRef","useCallback","useEffect","useRef","Keyboards","videoRef","useVideo","seekForward","seekBackward","useSeek","togglePlay","usePlayPause","toggleMute","useMuteUnmute","toggleFullscreen","useFullscreen","togglePictureInPicture","usePictureInPicture","useHotKeys","Fragment","jsx","jsxs","Video","forwardRef","src","autoPlay","muteFallback","controls","preload","autoPlayOnVisible","ranges","props","ref","videoRef","setVideoRef","config","setError","error","isFocused","useVideo","refVideo","useRef","isAdjustingRef","rafIdRef","timeoutIdRef","isValidRange","rangeStart","rangeEnd","useEffect","video","thirdPartyRef","useAutoplayByForce","useAutoplayOnVisible","onPlay","useCallback","_a","_b","_c","e","currentTime","Keyboards","React","useRef","Slot","React","useLoading","videoRef","isLoading","setIsLoading","video","handleLoadStart","handleLoadedMetadata","handleLoadedData","handleCanPlay","handleCanPlayThrough","handleWaiting","handlePlaying","handleError","handleAbort","handleSuspend","jsx","Controls","React","children","asChild","props","Play","Element","Slot","videoRef","useVideo","play","usePlayPause","Pause","pause","Mute","mute","useMuteUnmute","Unmute","unmute","Speed","value","onClick","speed","onChangeSpeed","useSpeed","SeekForward","seekForward","useSeek","SeekBackward","seekBackward","Fullscreen","toggleFullscreen","useFullscreen","ExitFullscreen","PictureInPicture","togglePictureInPicture","usePictureInPicture","Download","downloadDirect","useDownload","Loading","isLoading","useLoading","Shadow","shadowVideoRef","useRef","video","currentTime","isPlaying","interval","startInterval","stopInterval","handlePlay","handlePause"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.32",
6
+ "version": "0.1.34",
7
7
  "main": "./dist/index.js",
8
8
  "module": "./dist/index.mjs",
9
9
  "types": "./dist/index.d.ts",