@serifpersia/dango 3.5.6 → 3.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +2 -2
  2. package/client/dist/assets/{AnimeCard-B5chgVe0.js → AnimeCard-Vxac3CKU.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-CAIAwly1.js → AnimeInfo-z1nSbaco.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-QYTo62vI.js → AnimeInfoPage-Brb3TFXh.js} +2 -2
  5. package/client/dist/assets/{Asmr-BCfPv0s2.js → Asmr-BvM8UKQ3.js} +1 -1
  6. package/client/dist/assets/{AsmrResetProgressModal-yqEA3jOA.js → AsmrResetProgressModal-CndzdTHo.js} +1 -1
  7. package/client/dist/assets/{AvSyncCalibrator-DQb5AJBT.js → AvSyncCalibrator-XH4E6Sfp.js} +1 -1
  8. package/client/dist/assets/{Home-CyAIcLBV.js → Home-CW24x23t.js} +1 -1
  9. package/client/dist/assets/{Insights-CXAxHzhr.js → Insights-DLqUhamB.js} +1 -1
  10. package/client/dist/assets/{LibraryListPage-oQc9xuRt.js → LibraryListPage-BcHi-OIb.js} +1 -1
  11. package/client/dist/assets/{ListeningList-By91F5vR.js → ListeningList-gNfL7dv7.js} +1 -1
  12. package/client/dist/assets/{Manga-D7DgIXOq.js → Manga-B26xL6Dq.js} +1 -1
  13. package/client/dist/assets/{MangaInfoPage-Drk264JK.js → MangaInfoPage-CFI4_GgJ.js} +1 -1
  14. package/client/dist/assets/{MangaReadPage-CnmtQB51.js → MangaReadPage-CL2TKQc8.js} +1 -1
  15. package/client/dist/assets/{MangaResetProgressModal-irhuP8Mq.js → MangaResetProgressModal-yIv7jY4h.js} +1 -1
  16. package/client/dist/assets/{Mature-oAatUU-G.js → Mature-q8lBiSsb.js} +1 -1
  17. package/client/dist/assets/{MediaCard-DhBnuRF8.js → MediaCard-DM2d5vjg.js} +1 -1
  18. package/client/dist/assets/{Music-vX10ZW0N.js → Music-Dbswx5jU.js} +1 -1
  19. package/client/dist/assets/{OptionListMenu-C9D50WHH.js → OptionListMenu-BQnYYHpM.js} +1 -1
  20. package/client/dist/assets/{Player-C3glywqj.js → Player-lSQC6rcr.js} +2 -2
  21. package/client/dist/assets/{PlayerSettings-DnHFn6_a.js → PlayerSettings-Bns1A0RY.js} +1 -1
  22. package/client/dist/assets/{QueueOptionsButton-0GiAM-Bl.js → QueueOptionsButton-CGQAqTtM.js} +1 -1
  23. package/client/dist/assets/{QueueRail-CVLCaUMJ.js → QueueRail-ByOPjeHY.js} +1 -1
  24. package/client/dist/assets/{Radio-mP5TUQJn.js → Radio-C7BD7L1o.js} +1 -1
  25. package/client/dist/assets/{ReadingList-BCAszsYl.js → ReadingList-L0kcgqzm.js} +1 -1
  26. package/client/dist/assets/{ResetProgressModal-DLZmxatw.js → ResetProgressModal-aeUUSFYc.js} +1 -1
  27. package/client/dist/assets/{Search-DAMXgG2r.js → Search-DP0QouO-.js} +1 -1
  28. package/client/dist/assets/Settings-C7iOaCMq.js +21 -0
  29. package/client/dist/assets/{SkeletonGrid-D-ed9Fo4.js → SkeletonGrid-DyG9u20F.js} +1 -1
  30. package/client/dist/assets/{Trackers-DS90l3Q9.js → Trackers-COKJmOew.js} +1 -1
  31. package/client/dist/assets/Tv-QYoBwOlH.js +4 -0
  32. package/client/dist/assets/{TvInfo-BFVLnDNN.js → TvInfo-DS9pbimS.js} +1 -1
  33. package/client/dist/assets/{TvPopup-CHFaDWpi.js → TvPopup-C9Xhv1dW.js} +1 -1
  34. package/client/dist/assets/{TvSearch-B9lZQqIk.js → TvSearch-BjyAFYCg.js} +1 -1
  35. package/client/dist/assets/{TvWatchlist-Do2SUmoL.js → TvWatchlist-CAuCk-AT.js} +1 -1
  36. package/client/dist/assets/{Watchlist-C565Ujux.js → Watchlist-hgU-RPay.js} +1 -1
  37. package/client/dist/assets/{hls-B2witrNg.js → hls-E2REEW_P.js} +1 -1
  38. package/client/dist/assets/index-Ck-R0JKv.css +1 -0
  39. package/client/dist/assets/index-_iy8RyKU.js +178 -0
  40. package/client/dist/assets/{useAnimeInfoData-CUTE8CPy.js → useAnimeInfoData-CgmVQOsk.js} +1 -1
  41. package/client/dist/assets/{useAsmr-DRjNfYvY.js → useAsmr-BxU_JBAI.js} +1 -1
  42. package/client/dist/assets/{useAsmrPopup-Df06MY8X.js → useAsmrPopup-BYMMk2rG.js} +1 -1
  43. package/client/dist/assets/{useMangaLibrary-JyVVwSCn.js → useMangaLibrary-BrKhv-sI.js} +1 -1
  44. package/client/dist/assets/{useMangaPopup-BB1TZKW4.js → useMangaPopup-BQe7Ug-A.js} +1 -1
  45. package/client/dist/assets/{useProviders-Du7D_fOu.js → useProviders-swR4Flu5.js} +1 -1
  46. package/client/dist/assets/{useTv-C2YgiBMr.js → useTv-mq8TkTZl.js} +1 -1
  47. package/client/dist/assets/{useTvLibrary-DPO3DmuK.js → useTvLibrary-BuMreQuF.js} +1 -1
  48. package/client/dist/index.html +2 -2
  49. package/client/dist/repo_logo.svg +78 -0
  50. package/package.json +2 -2
  51. package/server/dist/trpc/routers/settings.js +1 -0
  52. package/server/package.json +1 -1
  53. package/client/dist/assets/Settings-DHC_FqKK.js +0 -21
  54. package/client/dist/assets/Tv-C9pmI-95.js +0 -4
  55. package/client/dist/assets/index-CFHNQtWr.js +0 -178
  56. package/client/dist/assets/index-w_r2lTCe.css +0 -1
  57. package/client/dist/logo.png +0 -0
@@ -1 +1 @@
1
- import{b as u,c as b,u as g,a as c}from"./vendor-query-BBT5_sHx.js";import{t as p,h as i,z as s}from"./index-CFHNQtWr.js";import{T as Q}from"./vendor-core-DfaOB3Rn.js";const v=300*1e3,M={mangadex:"https://mangadex.org/",mangapill:"https://www.mangapill.com/"},f=(e,a)=>`/api/proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(M[e])}`,T=(e,a)=>a&&(e==="mangapill"?f(e,a):a),k=(e,a=!0)=>{const{provider:r,query:n,page:o,sort:t,status:m,type:d,rating:y,mature:l}=e;return u({queryKey:["mangaBrowse",r,n,o,t,m,d,y,l],queryFn:()=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:o,sort:t||void 0,status:m||void 0,type:d||void 0,rating:y||void 0,mature:l?"1":void 0}),staleTime:v,enabled:a&&!!r})},E=(e,a=14)=>{const{provider:r,query:n,sort:o,status:t,type:m,rating:d,mature:y}=e;return b({queryKey:["mangaBrowseInfinite",r,n,o,t,m,d,y,a],queryFn:({pageParam:l=1})=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:l,limit:a,sort:o||void 0,status:t||void 0,type:m||void 0,rating:d||void 0,mature:y?"1":void 0}),initialPageParam:1,getNextPageParam:(l,q)=>l.hasNext?q.length+1:void 0,staleTime:v,enabled:!!r})},O=(e,a,r="safe",n=!1)=>u({queryKey:["mangaDetail",e,a,r,n],queryFn:()=>p.manga.info.query({provider:e||"",id:a||"",rating:r,mature:n?"1":void 0}),enabled:!!e&&!!a,staleTime:v}),$=(e,a,r)=>u({queryKey:["mangaPages",e,a],queryFn:()=>p.manga.pages.query({provider:e||"",id:a||""}),enabled:!!e&&!!a,staleTime:1800*1e3}),B=()=>{const e=i();return u({...e.manga.trending.queryOptions(),staleTime:600*1e3,retry:1})},I=e=>e.contentRating==="erotica"||e.contentRating==="pornographic"||e.type==="doujinshi";function N(e,a){const r=e.titles??{};return a==="englishName"?r.en||e.title:a==="nativeName"&&(r.native||r.romaji||e.altTitle)||e.title}function A(e){return{englishName:e.titles?.en??e.title,nativeName:e.titles?.native??e.titles?.romaji??e.altTitle??void 0}}const h=/^anilist:ch:(\d+)$/;function w(e){if(!e)return null;const a=h.exec(e.trim());if(!a)return null;const r=Number.parseInt(a[1],10);return Number.isFinite(r)?r:null}function x(e,a){const r=String(a),n=e.find(o=>(o.number??"").trim()===r);return n||(e.find(o=>{const t=Number.parseFloat((o.number??"").trim());return Number.isFinite(t)&&t===a})??null)}const _=["Reading","Completed","On-Hold","Dropped","Planned"],L=(e,a)=>`${e.toLowerCase()}:${a}`,D=(e="All",a=1,r=24)=>{const n=i();return u(n.mangaLibrary.list.queryOptions({status:e,page:a,limit:r}))},P=()=>{const e=i();return u({...e.mangaLibrary.ids.queryOptions(),staleTime:1e3*60})},U=e=>{const a=i();return u({...a.mangaLibrary.check.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},j=e=>{const a=i();return u({...a.mangaLibrary.entry.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},H=()=>{const e=i(),a=g();return c(e.mangaLibrary.link.mutationOptions({onSuccess:r=>{s.success(r?.progressMigrated?"Linked — chapter progress carried over":"Linked to AniList entry"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to link: ${r.message}`)}}))},z=(e=24)=>{const a=i();return u(a.mangaProgress.continueReading.queryOptions({limit:e}))},V=e=>{const a=i();return u({...a.mangaProgress.byManga.queryOptions({mangaId:e??""}),enabled:!!e})},S=()=>{const e=i(),a=g();return c(e.mangaLibrary.add.mutationOptions({onSuccess:(r,n)=>{n.silent||s.success("Bookmarked"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]})},onError:r=>{s.error(`Failed to bookmark: ${r.message}`)}}))},F=()=>{const e=i(),a=g();return c(e.mangaLibrary.remove.mutationOptions({onSuccess:()=>{s.success("Bookmark removed"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Y=()=>{const e=i(),a=g();return c(e.mangaLibrary.setStatus.mutationOptions({onSuccess:()=>{s.success("Status updated"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update status: ${r.message}`)}}))},G=()=>{const e=i(),a=g();return c(e.mangaProgress.save.mutationOptions({onSuccess:(r,n)=>{a.invalidateQueries({queryKey:["manga-progress",n.mangaId]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())}}))},J=()=>{const e=i(),a=g();return c(e.mangaProgress.remove.mutationOptions({onSuccess:()=>{s.success("Progress reset"),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},W=()=>{const e=i(),a=g();return c(e.mangaLibrary.batchStatus.mutationOptions({onSuccess:r=>{s.success(`Status updated for ${r.updated??0} items`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update statuses: ${r.message}`)}}))},X=()=>{const e=i(),a=g();return c(e.mangaLibrary.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Removed ${n} ${n===1?"item":"items"} from reading list`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Z=()=>{const e=i(),a=g();return c(e.mangaProgress.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Reset progress for ${n} ${n===1?"item":"items"}`),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},ee=()=>{const e=S(),a=F(),{data:r}=P(),n=Q(()=>new Set(r?.ids||[]),[r]);return{toggle:t=>{const m=L(t.provider,t.id);n.has(m)?a.mutate(m):e.mutate({provider:t.provider,mangaId:t.id,title:t.title,cover:t.cover,altTitle:t.altTitle,contentRating:t.contentRating})},bookmarkedIds:n,pending:e.isPending||a.isPending}};export{Z as A,J as B,_ as M,E as a,T as b,A as c,z as d,B as e,k as f,j as g,S as h,I as i,H as j,O as k,U as l,L as m,V as n,F as o,Y as p,w as q,N as r,x as s,$ as t,ee as u,f as v,G as w,D as x,W as y,X as z};
1
+ import{b as u,c as b,u as g,a as c}from"./vendor-query-BBT5_sHx.js";import{t as p,h as i,z as s}from"./index-_iy8RyKU.js";import{T as Q}from"./vendor-core-DfaOB3Rn.js";const v=300*1e3,M={mangadex:"https://mangadex.org/",mangapill:"https://www.mangapill.com/"},f=(e,a)=>`/api/proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(M[e])}`,T=(e,a)=>a&&(e==="mangapill"?f(e,a):a),k=(e,a=!0)=>{const{provider:r,query:n,page:o,sort:t,status:m,type:d,rating:y,mature:l}=e;return u({queryKey:["mangaBrowse",r,n,o,t,m,d,y,l],queryFn:()=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:o,sort:t||void 0,status:m||void 0,type:d||void 0,rating:y||void 0,mature:l?"1":void 0}),staleTime:v,enabled:a&&!!r})},E=(e,a=14)=>{const{provider:r,query:n,sort:o,status:t,type:m,rating:d,mature:y}=e;return b({queryKey:["mangaBrowseInfinite",r,n,o,t,m,d,y,a],queryFn:({pageParam:l=1})=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:l,limit:a,sort:o||void 0,status:t||void 0,type:m||void 0,rating:d||void 0,mature:y?"1":void 0}),initialPageParam:1,getNextPageParam:(l,q)=>l.hasNext?q.length+1:void 0,staleTime:v,enabled:!!r})},O=(e,a,r="safe",n=!1)=>u({queryKey:["mangaDetail",e,a,r,n],queryFn:()=>p.manga.info.query({provider:e||"",id:a||"",rating:r,mature:n?"1":void 0}),enabled:!!e&&!!a,staleTime:v}),$=(e,a,r)=>u({queryKey:["mangaPages",e,a],queryFn:()=>p.manga.pages.query({provider:e||"",id:a||""}),enabled:!!e&&!!a,staleTime:1800*1e3}),B=()=>{const e=i();return u({...e.manga.trending.queryOptions(),staleTime:600*1e3,retry:1})},I=e=>e.contentRating==="erotica"||e.contentRating==="pornographic"||e.type==="doujinshi";function N(e,a){const r=e.titles??{};return a==="englishName"?r.en||e.title:a==="nativeName"&&(r.native||r.romaji||e.altTitle)||e.title}function A(e){return{englishName:e.titles?.en??e.title,nativeName:e.titles?.native??e.titles?.romaji??e.altTitle??void 0}}const h=/^anilist:ch:(\d+)$/;function w(e){if(!e)return null;const a=h.exec(e.trim());if(!a)return null;const r=Number.parseInt(a[1],10);return Number.isFinite(r)?r:null}function x(e,a){const r=String(a),n=e.find(o=>(o.number??"").trim()===r);return n||(e.find(o=>{const t=Number.parseFloat((o.number??"").trim());return Number.isFinite(t)&&t===a})??null)}const _=["Reading","Completed","On-Hold","Dropped","Planned"],L=(e,a)=>`${e.toLowerCase()}:${a}`,D=(e="All",a=1,r=24)=>{const n=i();return u(n.mangaLibrary.list.queryOptions({status:e,page:a,limit:r}))},P=()=>{const e=i();return u({...e.mangaLibrary.ids.queryOptions(),staleTime:1e3*60})},U=e=>{const a=i();return u({...a.mangaLibrary.check.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},j=e=>{const a=i();return u({...a.mangaLibrary.entry.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},H=()=>{const e=i(),a=g();return c(e.mangaLibrary.link.mutationOptions({onSuccess:r=>{s.success(r?.progressMigrated?"Linked — chapter progress carried over":"Linked to AniList entry"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to link: ${r.message}`)}}))},z=(e=24)=>{const a=i();return u(a.mangaProgress.continueReading.queryOptions({limit:e}))},V=e=>{const a=i();return u({...a.mangaProgress.byManga.queryOptions({mangaId:e??""}),enabled:!!e})},S=()=>{const e=i(),a=g();return c(e.mangaLibrary.add.mutationOptions({onSuccess:(r,n)=>{n.silent||s.success("Bookmarked"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]})},onError:r=>{s.error(`Failed to bookmark: ${r.message}`)}}))},F=()=>{const e=i(),a=g();return c(e.mangaLibrary.remove.mutationOptions({onSuccess:()=>{s.success("Bookmark removed"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Y=()=>{const e=i(),a=g();return c(e.mangaLibrary.setStatus.mutationOptions({onSuccess:()=>{s.success("Status updated"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update status: ${r.message}`)}}))},G=()=>{const e=i(),a=g();return c(e.mangaProgress.save.mutationOptions({onSuccess:(r,n)=>{a.invalidateQueries({queryKey:["manga-progress",n.mangaId]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())}}))},J=()=>{const e=i(),a=g();return c(e.mangaProgress.remove.mutationOptions({onSuccess:()=>{s.success("Progress reset"),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},W=()=>{const e=i(),a=g();return c(e.mangaLibrary.batchStatus.mutationOptions({onSuccess:r=>{s.success(`Status updated for ${r.updated??0} items`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update statuses: ${r.message}`)}}))},X=()=>{const e=i(),a=g();return c(e.mangaLibrary.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Removed ${n} ${n===1?"item":"items"} from reading list`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Z=()=>{const e=i(),a=g();return c(e.mangaProgress.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Reset progress for ${n} ${n===1?"item":"items"}`),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},ee=()=>{const e=S(),a=F(),{data:r}=P(),n=Q(()=>new Set(r?.ids||[]),[r]);return{toggle:t=>{const m=L(t.provider,t.id);n.has(m)?a.mutate(m):e.mutate({provider:t.provider,mangaId:t.id,title:t.title,cover:t.cover,altTitle:t.altTitle,contentRating:t.contentRating})},bookmarkedIds:n,pending:e.isPending||a.isPending}};export{Z as A,J as B,_ as M,E as a,T as b,A as c,z as d,B as e,k as f,j as g,S as h,I as i,H as j,O as k,U as l,L as m,V as n,F as o,Y as p,w as q,N as r,x as s,$ as t,ee as u,f as v,G as w,D as x,W as y,X as z};
@@ -1 +1 @@
1
- import{u as e,S as f,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as l}from"./vendor-icons-DrybRNxP.js";import{k as y,r as T}from"./useMangaLibrary-JyVVwSCn.js";import{d as I}from"./index-CFHNQtWr.js";import{p as s,a as k}from"./MediaCard-DhBnuRF8.js";import{u as P}from"./usePopup-DS9jMzp6.js";const R=({data:i,anchorRect:d,bookmarked:r,onToggleBookmark:p,onMouseEnter:h,onMouseLeave:v,onRequestClose:g})=>{const{data:a,isLoading:N}=y(i.provider,i.mangaId,i.rating||"safe",i.mature||!1),{titlePreference:u}=I(),t=a?.chapters.length??0,c=[a?.status,a?.type].filter(Boolean).join(" · "),o=T({title:i.title,altTitle:a?.altTitle??i.altTitle},u);return e(k,{anchorRect:d,onMouseEnter:h,onMouseLeave:v,onRequestClose:g,children:N?e("div",{className:s.loading,children:[e("div",{className:s.spinner}),e("span",{children:"Fetching details..."})]}):e(f,{children:[e("div",{className:s.header,children:[e("div",{className:s.title,children:o}),a?.altTitle&&a.altTitle!==o&&e("div",{className:s.synopsis,children:["Also known as: ",a.altTitle]})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[c&&e("div",{className:s.metaItem,children:[e(l,{name:"book",size:14}),e("span",{children:c})]}),t>0&&e("div",{className:s.metaItem,children:e("span",{children:[t," chapter",t===1?"":"s"]})}),i.progressLabel&&e("div",{className:s.metaItem,children:[e(l,{name:"bookmark",size:12}),e("span",{children:i.progressLabel})]})]}),e("div",{className:s.synopsis,children:a?.description?a.description:"No synopsis available."}),Array.isArray(a?.genres)&&(a?.genres?.length??0)>0&&e("div",{className:s.details,children:e("div",{className:s.genres,children:a.genres.filter(Boolean).slice(0,4).map(n=>e("span",{className:s.genre,children:n},n))})})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:e(m,{to:i.readTarget,className:s.watchBtn,children:[e(l,{name:"book",size:14}),"Read now"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${r?s.active:""}`,onClick:n=>{n.preventDefault(),n.stopPropagation(),p()},children:[r?e(l,{name:"check",size:12}):e(l,{name:"plus",size:12}),e("span",{children:r?"Remove":"Bookmark"})]}),e(m,{to:`/manga/${i.provider}/${encodeURIComponent(i.mangaId)}`,className:s.detailsBtn,children:"Read more"})]})]})]})})},$=()=>P();export{R as M,$ as u};
1
+ import{u as e,S as f,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as l}from"./vendor-icons-DrybRNxP.js";import{k as y,r as T}from"./useMangaLibrary-BrKhv-sI.js";import{d as I}from"./index-_iy8RyKU.js";import{p as s,a as k}from"./MediaCard-DM2d5vjg.js";import{u as P}from"./usePopup-DS9jMzp6.js";const R=({data:i,anchorRect:d,bookmarked:r,onToggleBookmark:p,onMouseEnter:h,onMouseLeave:v,onRequestClose:g})=>{const{data:a,isLoading:N}=y(i.provider,i.mangaId,i.rating||"safe",i.mature||!1),{titlePreference:u}=I(),t=a?.chapters.length??0,c=[a?.status,a?.type].filter(Boolean).join(" · "),o=T({title:i.title,altTitle:a?.altTitle??i.altTitle},u);return e(k,{anchorRect:d,onMouseEnter:h,onMouseLeave:v,onRequestClose:g,children:N?e("div",{className:s.loading,children:[e("div",{className:s.spinner}),e("span",{children:"Fetching details..."})]}):e(f,{children:[e("div",{className:s.header,children:[e("div",{className:s.title,children:o}),a?.altTitle&&a.altTitle!==o&&e("div",{className:s.synopsis,children:["Also known as: ",a.altTitle]})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[c&&e("div",{className:s.metaItem,children:[e(l,{name:"book",size:14}),e("span",{children:c})]}),t>0&&e("div",{className:s.metaItem,children:e("span",{children:[t," chapter",t===1?"":"s"]})}),i.progressLabel&&e("div",{className:s.metaItem,children:[e(l,{name:"bookmark",size:12}),e("span",{children:i.progressLabel})]})]}),e("div",{className:s.synopsis,children:a?.description?a.description:"No synopsis available."}),Array.isArray(a?.genres)&&(a?.genres?.length??0)>0&&e("div",{className:s.details,children:e("div",{className:s.genres,children:a.genres.filter(Boolean).slice(0,4).map(n=>e("span",{className:s.genre,children:n},n))})})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:e(m,{to:i.readTarget,className:s.watchBtn,children:[e(l,{name:"book",size:14}),"Read now"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${r?s.active:""}`,onClick:n=>{n.preventDefault(),n.stopPropagation(),p()},children:[r?e(l,{name:"check",size:12}):e(l,{name:"plus",size:12}),e("span",{children:r?"Remove":"Bookmark"})]}),e(m,{to:`/manga/${i.provider}/${encodeURIComponent(i.mangaId)}`,className:s.detailsBtn,children:"Read more"})]})]})]})})},$=()=>P();export{R as M,$ as u};
@@ -1 +1 @@
1
- import{T as o}from"./vendor-core-DfaOB3Rn.js";import{b as a}from"./vendor-query-BBT5_sHx.js";import{U as i}from"./index-CFHNQtWr.js";const n=300*1e3;function u(r){return{value:r.id,label:r.label,mature:r.mature,kind:r.kind,sub:r.sub,tier:r.tier,browse:r.browse,facets:r.facets,servers:r.servers}}const d=()=>{const r=a({queryKey:["providers"],queryFn:()=>i("/api/providers"),staleTime:n,retry:1}),e=Array.isArray(r.data)?r.data:null,t=o(()=>e&&e.length>0?e.filter(s=>s.loaded).map(u):[],[e]);return{...r,options:t,isFallback:!e||e.length===0}};export{d as u};
1
+ import{T as o}from"./vendor-core-DfaOB3Rn.js";import{b as a}from"./vendor-query-BBT5_sHx.js";import{U as i}from"./index-_iy8RyKU.js";const n=300*1e3;function u(r){return{value:r.id,label:r.label,mature:r.mature,kind:r.kind,sub:r.sub,tier:r.tier,browse:r.browse,facets:r.facets,servers:r.servers}}const d=()=>{const r=a({queryKey:["providers"],queryFn:()=>i("/api/providers"),staleTime:n,retry:1}),e=Array.isArray(r.data)?r.data:null,t=o(()=>e&&e.length>0?e.filter(s=>s.loaded).map(u):[],[e]);return{...r,options:t,isFallback:!e||e.length===0}};export{d as u};
@@ -1 +1 @@
1
- import{N as c,u as r,S as d}from"./vendor-core-DfaOB3Rn.js";import{I as v}from"./vendor-icons-DrybRNxP.js";import{M as T}from"./MediaCard-DhBnuRF8.js";import{T as g}from"./TvPopup-CHFaDWpi.js";import{c as m,i as f}from"./useTvLibrary-DPO3DmuK.js";import{b as i}from"./vendor-query-BBT5_sHx.js";import{h as p}from"./index-CFHNQtWr.js";const _=c(({item:e})=>{const o=e.type==="tv"||e.type==="tvSeries"||e.type==="tvMiniSeries",s=m(e.type,e.id);return r(T,{item:{id:String(e.id),title:e.title,thumbnail:e.image,typeBadge:o?"TV":"Movie",isAdult:f(e)},linkTo:s,hoverIcon:"info",showInfoButton:!0,metaRow:r(d,{children:[e.year&&r("span",{style:{opacity:.75},children:e.year}),e.vote_average!=null&&r("span",{style:{display:"inline-flex",alignItems:"center",gap:3},children:[r(v,{name:"star",size:10}),Number(e.vote_average).toFixed(1)]})]}),renderPopup:(a,t)=>r(g,{item:e,anchorRect:a,onMouseEnter:t.onMouseEnter,onMouseLeave:t.onMouseLeave,onRequestClose:t.close})})}),u=1e3*60*5,b=e=>{const o=p(),{query:s,type:a,genre:t,year:n,sort_by:l,page:y}=e;return i({...o.tv.search.queryOptions({q:s?.trim()||"",type:a||"multi",genre:t||"",year:n&&n!=="ALL"?n:"",sortBy:l||"popularity.desc",page:y||1}),staleTime:u,retry:1})},A=(e="all",o="week",s=1,a=!0)=>{const t=p();return i({...t.tv.trending.queryOptions({mediaType:e,timeWindow:o,page:s}),enabled:a,staleTime:u,retry:1})};export{_ as T,b as a,A as u};
1
+ import{N as c,u as r,S as d}from"./vendor-core-DfaOB3Rn.js";import{I as v}from"./vendor-icons-DrybRNxP.js";import{M as T}from"./MediaCard-DM2d5vjg.js";import{T as g}from"./TvPopup-C9Xhv1dW.js";import{c as m,i as f}from"./useTvLibrary-BuMreQuF.js";import{b as i}from"./vendor-query-BBT5_sHx.js";import{h as p}from"./index-_iy8RyKU.js";const _=c(({item:e})=>{const o=e.type==="tv"||e.type==="tvSeries"||e.type==="tvMiniSeries",s=m(e.type,e.id);return r(T,{item:{id:String(e.id),title:e.title,thumbnail:e.image,typeBadge:o?"TV":"Movie",isAdult:f(e)},linkTo:s,hoverIcon:"info",showInfoButton:!0,metaRow:r(d,{children:[e.year&&r("span",{style:{opacity:.75},children:e.year}),e.vote_average!=null&&r("span",{style:{display:"inline-flex",alignItems:"center",gap:3},children:[r(v,{name:"star",size:10}),Number(e.vote_average).toFixed(1)]})]}),renderPopup:(a,t)=>r(g,{item:e,anchorRect:a,onMouseEnter:t.onMouseEnter,onMouseLeave:t.onMouseLeave,onRequestClose:t.close})})}),u=1e3*60*5,b=e=>{const o=p(),{query:s,type:a,genre:t,year:n,sort_by:l,page:y}=e;return i({...o.tv.search.queryOptions({q:s?.trim()||"",type:a||"multi",genre:t||"",year:n&&n!=="ALL"?n:"",sortBy:l||"popularity.desc",page:y||1}),staleTime:u,retry:1})},A=(e="all",o="week",s=1,a=!0)=>{const t=p();return i({...t.tv.trending.queryOptions({mediaType:e,timeWindow:o,page:s}),enabled:a,staleTime:u,retry:1})};export{_ as T,b as a,A as u};
@@ -1 +1 @@
1
- import{T as y}from"./vendor-core-DfaOB3Rn.js";import{b as v,u as o,a as n}from"./vendor-query-BBT5_sHx.js";import{h as a,z as i,t as p}from"./index-CFHNQtWr.js";const d=t=>String(t).toLowerCase()==="movie"?"movie":"tv",m=(t,e)=>`${d(t)}:${e}`,L=(t,e)=>{const r=d(t);return`/tv/${e}?type=${r}`},S=(t,e,r,s)=>{const u=new URLSearchParams;return u.set("type",d(t)),r!==void 0&&u.set("s",String(r)),s!==void 0&&u.set("e",String(s)),`/tv/${e}/watch?${u.toString()}`},F=t=>t.adult===!0||t.adult===1,K=["Watching","Completed","On-Hold","Dropped","Planned"],g=(t,e)=>m(t,e),$=(t="All",e=1,r=24)=>{const s=a();return v(s.tvLibrary.list.queryOptions({status:t,page:e,limit:r}))},h=()=>{const t=a();return v({...t.tvLibrary.ids.queryOptions(),staleTime:1e3*60})},C=t=>{const e=a();return v({...e.tvLibrary.check.queryOptions({id:t||""}),enabled:!!t,staleTime:1e3*60})},w=(t=24)=>{const e=a();return v(e.tvProgress.continueWatching.queryOptions({limit:t}))},O=t=>{const e=a();return v({...e.tvProgress.getByMedia.queryOptions({mediaId:t||""}),enabled:!!t})},f=(t,e,r)=>{const s=a();return v({...s.tvProgress.latest.queryOptions({mediaId:t||"",season:e,episode:r}),enabled:!!t,staleTime:0})},b=()=>{const t=a(),e=o();return n({mutationFn:async r=>{const{silent:s,...u}=r;return p.tvLibrary.add.mutate(u)},onSuccess:(r,s)=>{s.silent||i.success("Added to TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter())},onError:r=>{i.error(`Failed to add: ${r.message}`)}})},Q=()=>{const t=a(),e=o();return n(t.tvLibrary.remove.mutationOptions({onSuccess:()=>{i.success("Removed from TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},k=()=>{const t=a(),e=o();return n(t.tvLibrary.setStatus.mutationOptions({onSuccess:()=>{i.success("Status updated"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update status: ${r.message}`)}}))},R=()=>{const t=a(),e=o();return n(t.tvProgress.save.mutationOptions({onSuccess:(r,s)=>{e.invalidateQueries({queryKey:["tv-progress",s.mediaId]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())}}))},B=()=>{const t=a(),e=o();return n(t.tvProgress.remove.mutationOptions({onSuccess:()=>{i.success("Progress reset"),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},E=()=>{const t=a(),e=o();return n(t.tvLibrary.batchStatus.mutationOptions({onSuccess:r=>{i.success(`Status updated for ${r.updated??0} items`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update statuses: ${r.message}`)}}))},I=()=>{const t=a(),e=o();return n(t.tvLibrary.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Removed ${s} ${s===1?"item":"items"} from TV watchlist`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},A=()=>{const t=a(),e=o();return n(t.tvProgress.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Reset progress for ${s} ${s===1?"item":"items"}`),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},M=()=>{const t=b(),e=Q(),{data:r}=h(),s=y(()=>new Set(r?.ids||[]),[r]);return{toggle:c=>{const l=g(c.mediaType,c.tmdbId);s.has(l)?e.mutate(l):t.mutate({...c,poster:c.poster||""})},bookmarkedIds:s,pending:t.isPending||e.isPending}};export{K as T,Q as a,B as b,L as c,m as d,C as e,M as f,R as g,k as h,F as i,f as j,O as k,$ as l,E as m,d as n,I as o,A as p,S as t,w as u};
1
+ import{T as y}from"./vendor-core-DfaOB3Rn.js";import{b as v,u as o,a as n}from"./vendor-query-BBT5_sHx.js";import{h as a,z as i,t as p}from"./index-_iy8RyKU.js";const d=t=>String(t).toLowerCase()==="movie"?"movie":"tv",m=(t,e)=>`${d(t)}:${e}`,L=(t,e)=>{const r=d(t);return`/tv/${e}?type=${r}`},S=(t,e,r,s)=>{const u=new URLSearchParams;return u.set("type",d(t)),r!==void 0&&u.set("s",String(r)),s!==void 0&&u.set("e",String(s)),`/tv/${e}/watch?${u.toString()}`},F=t=>t.adult===!0||t.adult===1,K=["Watching","Completed","On-Hold","Dropped","Planned"],g=(t,e)=>m(t,e),$=(t="All",e=1,r=24)=>{const s=a();return v(s.tvLibrary.list.queryOptions({status:t,page:e,limit:r}))},h=()=>{const t=a();return v({...t.tvLibrary.ids.queryOptions(),staleTime:1e3*60})},C=t=>{const e=a();return v({...e.tvLibrary.check.queryOptions({id:t||""}),enabled:!!t,staleTime:1e3*60})},w=(t=24)=>{const e=a();return v(e.tvProgress.continueWatching.queryOptions({limit:t}))},O=t=>{const e=a();return v({...e.tvProgress.getByMedia.queryOptions({mediaId:t||""}),enabled:!!t})},f=(t,e,r)=>{const s=a();return v({...s.tvProgress.latest.queryOptions({mediaId:t||"",season:e,episode:r}),enabled:!!t,staleTime:0})},b=()=>{const t=a(),e=o();return n({mutationFn:async r=>{const{silent:s,...u}=r;return p.tvLibrary.add.mutate(u)},onSuccess:(r,s)=>{s.silent||i.success("Added to TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter())},onError:r=>{i.error(`Failed to add: ${r.message}`)}})},Q=()=>{const t=a(),e=o();return n(t.tvLibrary.remove.mutationOptions({onSuccess:()=>{i.success("Removed from TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},k=()=>{const t=a(),e=o();return n(t.tvLibrary.setStatus.mutationOptions({onSuccess:()=>{i.success("Status updated"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update status: ${r.message}`)}}))},R=()=>{const t=a(),e=o();return n(t.tvProgress.save.mutationOptions({onSuccess:(r,s)=>{e.invalidateQueries({queryKey:["tv-progress",s.mediaId]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())}}))},B=()=>{const t=a(),e=o();return n(t.tvProgress.remove.mutationOptions({onSuccess:()=>{i.success("Progress reset"),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},E=()=>{const t=a(),e=o();return n(t.tvLibrary.batchStatus.mutationOptions({onSuccess:r=>{i.success(`Status updated for ${r.updated??0} items`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update statuses: ${r.message}`)}}))},I=()=>{const t=a(),e=o();return n(t.tvLibrary.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Removed ${s} ${s===1?"item":"items"} from TV watchlist`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},A=()=>{const t=a(),e=o();return n(t.tvProgress.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Reset progress for ${s} ${s===1?"item":"items"}`),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},M=()=>{const t=b(),e=Q(),{data:r}=h(),s=y(()=>new Set(r?.ids||[]),[r]);return{toggle:c=>{const l=g(c.mediaType,c.tmdbId);s.has(l)?e.mutate(l):t.mutate({...c,poster:c.poster||""})},bookmarkedIds:s,pending:t.isPending||e.isPending}};export{K as T,Q as a,B as b,L as c,m as d,C as e,M as f,R as g,k as h,F as i,f as j,O as k,$ as l,E as m,d as n,I as o,A as p,S as t,w as u};
@@ -33,11 +33,11 @@
33
33
  background-color: #0c0d12;
34
34
  }
35
35
  </style>
36
- <script type="module" crossorigin src="/assets/index-CFHNQtWr.js"></script>
36
+ <script type="module" crossorigin src="/assets/index-_iy8RyKU.js"></script>
37
37
  <link rel="modulepreload" crossorigin href="/assets/vendor-core-DfaOB3Rn.js">
38
38
  <link rel="modulepreload" crossorigin href="/assets/vendor-query-BBT5_sHx.js">
39
39
  <link rel="modulepreload" crossorigin href="/assets/vendor-icons-DrybRNxP.js">
40
- <link rel="stylesheet" crossorigin href="/assets/index-w_r2lTCe.css">
40
+ <link rel="stylesheet" crossorigin href="/assets/index-Ck-R0JKv.css">
41
41
  </head>
42
42
 
43
43
  <body>
@@ -0,0 +1,78 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ width="14.5"
4
+ height="11.1"
5
+ viewBox="-0.45 -0.45 14.5 11.1"
6
+ version="1.1"
7
+ id="svg3"
8
+ sodipodi:docname="repo_logo.svg"
9
+ xml:space="preserve"
10
+ inkscape:version="1.4.4 (dcaf3e7, 2026-05-05)"
11
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
13
+ xmlns="http://www.w3.org/2000/svg"
14
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
15
+ id="defs3" /><sodipodi:namedview
16
+ id="namedview3"
17
+ pagecolor="#505050"
18
+ bordercolor="#eeeeee"
19
+ borderopacity="1"
20
+ inkscape:showpageshadow="0"
21
+ inkscape:pageopacity="0"
22
+ inkscape:pagecheckerboard="0"
23
+ inkscape:deskcolor="#505050"
24
+ inkscape:zoom="25.518017"
25
+ inkscape:cx="6.0349517"
26
+ inkscape:cy="8.6409535"
27
+ inkscape:window-width="2560"
28
+ inkscape:window-height="1351"
29
+ inkscape:window-x="-9"
30
+ inkscape:window-y="-9"
31
+ inkscape:window-maximized="1"
32
+ inkscape:current-layer="svg3" /><g
33
+ inkscape:groupmode="layer"
34
+ id="layer1"
35
+ inkscape:label="Layer 1"><path
36
+ fill="#e1afef"
37
+ stroke="#a978a9"
38
+ stroke-width="0.9"
39
+ stroke-linejoin="round"
40
+ paint-order="stroke fill"
41
+ d="M 7.0022839,-1.1920929e-8 C 3.0649855,-1.1920929e-8 -0.09802047,2.4883888 0.0022839,6 c 0.13572675,4.751733 5.0802847,4.156395 7,4.156395 1.2538994,0 6.5304511,0.392468 6.5849461,-4.168088 C 13.62431,2.8853946 10.939582,-1.1920929e-8 7.0022839,-1.1920929e-8 Z"
42
+ id="path1" /><path
43
+ fill="#140f15"
44
+ d="m 4.9623825,3.416 c -0.5858889,0 -0.6520292,2.3368563 -0.024765,2.3368563 0.6604959,0 0.6704653,-2.3368563 0.024765,-2.3368563 z"
45
+ id="path2" /><path
46
+ fill="#140f15"
47
+ d="M 8.588001,3.416 C 8.0021121,3.416 7.9359718,5.7528563 8.563236,5.7528563 9.2237319,5.7528563 9.2337013,3.416 8.588001,3.416 Z"
48
+ id="path3" /></g><g
49
+ id="g4"
50
+ transform="translate(12.231148,1.5056648)"><path
51
+ fill="#e3e1ee"
52
+ stroke="#b3b1c6"
53
+ stroke-width="0.9"
54
+ stroke-linejoin="round"
55
+ paint-order="stroke fill"
56
+ d="m 7,0 c -3.9372984,0 -7.10030437,2.4883888 -7,6 0.13572675,4.751733 5.0802847,4.156395 7,4.156395 1.2538994,0 6.530451,0.392468 6.584946,-4.168088 C 13.622023,2.8853946 10.937298,0 7,0 Z"
57
+ id="path1-5" /><path
58
+ fill="#140f15"
59
+ d="m 3.3556746,2.945744 c -0.5858889,0 -0.6520292,2.3368563 -0.024765,2.3368563 0.6604959,0 0.6704653,-2.3368563 0.024765,-2.3368563 z"
60
+ id="path2-7" /><path
61
+ fill="#140f15"
62
+ d="m 6.9812931,2.945744 c -0.5858889,0 -0.6520292,2.3368563 -0.024765,2.3368563 0.6604959,0 0.6704653,-2.3368563 0.024765,-2.3368563 z"
63
+ id="path3-6" /></g><g
64
+ id="g3"
65
+ transform="translate(-11.063909,1.423053)"><path
66
+ fill="#897cff"
67
+ stroke="#5646db"
68
+ stroke-width="0.9"
69
+ stroke-linejoin="round"
70
+ paint-order="stroke fill"
71
+ d="m 7,0 c -3.9372984,0 -7.10030437,2.4883888 -7,6 0.13572675,4.751733 5.0802847,4.156395 7,4.156395 1.2538994,0 6.530451,0.392468 6.584946,-4.168088 C 13.622023,2.8853946 10.937298,0 7,0 Z"
72
+ id="path1-3" /><path
73
+ fill="#140f15"
74
+ d="m 7.3136624,3.376812 c -0.5858889,0 -0.6520292,2.3368563 -0.024765,2.3368563 0.6604959,0 0.6704653,-2.3368563 0.024765,-2.3368563 z"
75
+ id="path2-2" /><path
76
+ fill="#140f15"
77
+ d="m 10.939281,3.376812 c -0.585889,0 -0.652029,2.3368563 -0.02476,2.3368563 0.660496,0 0.670465,-2.3368563 0.02476,-2.3368563 z"
78
+ id="path3-2" /></g></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serifpersia/dango",
3
- "version": "3.5.6",
3
+ "version": "3.5.8",
4
4
  "description": "A web application for watching anime.",
5
5
  "main": "orchestrator.js",
6
6
  "repository": {
@@ -83,5 +83,5 @@
83
83
  "allowScripts": {
84
84
  "esbuild@0.28.2": true
85
85
  },
86
- "versionDate": "2026-10-11T16:04:28.902Z"
86
+ "versionDate": "2026-10-13T22:36:05.242Z"
87
87
  }
@@ -12,6 +12,7 @@ import { keyInput, setSettingInput } from '../validation.js';
12
12
  export const SETTING_DEFAULTS = {
13
13
  discordRPCEnabled: 'true',
14
14
  discordRPCHideMature: 'true',
15
+ dangoGaze: 'true',
15
16
  ignoreAdultContent: 'true',
16
17
  mangaIgnoreAdultContent: 'true',
17
18
  tvIgnoreAdultContent: 'true',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dango-server",
3
3
  "private": true,
4
- "version": "3.5.6",
4
+ "version": "3.5.8",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.12.0"
@@ -1,21 +0,0 @@
1
- import{d as s,A as H,h as G,u as e,q as ae,S as fe,T as ve,p as we,g as re,_ as be}from"./vendor-core-DfaOB3Rn.js";import{d as ke,t as _,B as T,M as $,j as ce,h as Ce,z as ie,F as X,G as _e,T as Se,u as Ne,e as Te,H as Ie,y as oe,A as Re,V as xe,I as Le}from"./index-CFHNQtWr.js";import{u as ne}from"./vendor-query-BBT5_sHx.js";import{T as K}from"./ToggleSwitch-CN_ppEc9.js";import{I as Y}from"./vendor-icons-DrybRNxP.js";const Z={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},ee=["name","nativeName","englishName"],te={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},De=()=>{const{titlePreference:t,setTitlePreference:r,loading:i}=ke(),[l,o]=s(te[t]),[v,b]=s(!1),h=H(null);G(()=>{i||o(te[t])},[t,i]);const a=async()=>{if(v)return;b(!0);const g=(ee.indexOf(t)+1)%ee.length,m=ee[g],d=te[m];h.current&&(h.current.style.transform="translateX(-100%)",h.current.style.opacity="0"),setTimeout(async()=>{o(d),r(m),h.current&&(h.current.style.transition="none",h.current.style.transform="translateX(100%)",h.current.style.opacity="0",h.current.offsetWidth,h.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",h.current.style.transform="translateX(0)",h.current.style.opacity="1");try{await _.settings.set.mutate({key:"titlePreference",value:m})}catch(S){console.error("Error saving title preference:",S)}finally{b(!1)}},300)};return i?e("p",{children:"Loading title preference..."}):e("div",{className:Z["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:a,className:Z["toggle-button"],disabled:v,children:e("span",{ref:h,className:Z["toggle-label"],children:l})})]})},Pe="_settingsHeader_14a5d_1",Ae="_pageTitle_14a5d_6",Oe="_pageSubtitle_14a5d_14",Me="_settingsLayout_14a5d_20",Ge="_sidebar_14a5d_27",Ue="_sidebarIndicator_14a5d_35",Ee="_sidebarItem_14a5d_50",$e="_active_14a5d_72",ze="_mainContent_14a5d_80",qe="_tabContent_14a5d_85",Fe="_sectionCard_14a5d_103",Ke="_settingItem_14a5d_127",je="_settingRow_14a5d_132",He="_controls_14a5d_145",We="_status_14a5d_151",p={settingsHeader:Pe,pageTitle:Ae,pageSubtitle:Oe,settingsLayout:Me,sidebar:Ge,sidebarIndicator:Ue,sidebarItem:Ee,active:$e,mainContent:ze,tabContent:qe,sectionCard:Fe,settingItem:Ke,settingRow:je,controls:He,status:We},Be="_sectionCard_wt900_12",Ve="_title_wt900_22",Qe="_signIn_wt900_29",Ye="_userInfo_wt900_36",Je="_warning_wt900_58",Xe="_formGroup_wt900_65",Ze="_label_wt900_69",et="_inputWrapper_wt900_79",tt="_input_wt900_79",at="_select_wt900_103",nt="_actions_wt900_140",st="_hr_wt900_148",u={sectionCard:Be,title:Ve,signIn:Qe,userInfo:Ye,warning:Je,formGroup:Xe,label:Ze,inputWrapper:et,input:tt,select:at,actions:nt,hr:st},rt=()=>{const[t,r]=s(!0),[i,l]=s(!1),[o,v]=s(!1),[b,h]=s(null),[a,c]=s({status:"idle"}),[g,m]=s(!1),[d,S]=s(""),[y,k]=s(!1),R=H(null),[x,L]=s({show:!1,message:"",type:"info"}),D=()=>{R.current&&(window.clearInterval(R.current),R.current=null)},w=ae(f=>{v(f.authenticated),h(f.user||f.device.user||null),c(f.device),m(!!f.hasCustomClientId)},[]),C=ae(async()=>{const f=await _.auth.githubStatus.query();w(f)},[w]),A=async()=>{try{const f=await _.auth.githubPoll.query();c(f),f.status==="success"?(D(),await C(),L({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):f.status==="error"&&(D(),L({show:!0,message:f.error||"GitHub authentication failed.",type:"error"}))}catch{D(),L({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},U=(f=5)=>{D(),R.current=window.setInterval(A,Math.max(f,5)*1e3)};G(()=>(C().catch(()=>{L({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>r(!1)),D),[C]);const N=async()=>{l(!0);try{const f=await _.auth.githubStart.mutate();c(f),U(f.verification?.interval)}catch(f){L({show:!0,message:f instanceof Error?f.message:"Failed to start GitHub authentication.",type:"error"})}finally{l(!1)}},P=async()=>{try{await _.auth.githubLogout.mutate(),v(!1),h(null),c({status:"idle"}),L({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{L({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},O=async()=>{k(!0);try{await _.auth.saveGithubAuth.mutate({clientId:d}),S(""),await C(),L({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{L({show:!0,message:"Failed to save override.",type:"error"})}finally{k(!1)}},q=async()=>{k(!0);try{await _.auth.saveGithubAuth.mutate({clientId:""}),S(""),await C(),L({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{L({show:!0,message:"Failed to clear override.",type:"error"})}finally{k(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:u.sectionCard,children:[e("h3",{className:u.title,children:"GitHub Cloud Sync"}),e("p",{className:u.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),o&&b?e("div",{className:u.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:b.name||b.login})]}),e(T,{variant:"danger",onClick:P,children:"Sign Out"})]}):e("div",{className:u.signIn,children:e(T,{onClick:N,disabled:i||a.status==="pending",children:i||a.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),a.status==="pending"&&a.verification&&e(fe,{children:[e("hr",{className:u.hr}),e("div",{className:u.formGroup,children:[e("label",{className:u.label,children:"Verification URL"}),e("div",{className:u.inputWrapper,children:[e("input",{className:u.input,value:a.verification.verification_uri,readOnly:!0}),e(T,{onClick:()=>{const f=a.verification?.verification_uri;f&&/^https?:\/\//i.test(f)&&window.open(f,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:u.formGroup,children:[e("label",{className:u.label,children:"Device Code"}),e("input",{className:u.input,value:a.verification.user_code,readOnly:!0})]})]}),a.status==="error"&&e("p",{className:u.warning,children:a.error}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",g?"(override active)":""]}),e("div",{className:u.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:u.label,children:"Client ID (optional)"}),e("input",{className:u.input,value:d,onChange:f=>S(f.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:u.actions,children:[e(T,{onClick:O,disabled:y,children:"Save override"}),e(T,{variant:"secondary",onClick:q,disabled:y,children:"Use dango defaults"})]})]}),e($,{isOpen:x.show,onClose:()=>L(f=>({...f,show:!1})),width:"sm",children:[e($.Body,{children:e("p",{children:x.message})}),e($.Actions,{children:e(T,{onClick:()=>L(f=>({...f,show:!1})),children:"OK"})})]})]})},it=()=>{const[t,r]=s(!0),[i,l]=s(null),[o,v]=s(!1),[b,h]=s(!1),[a,c]=s(""),[g,m]=s(""),[d,S]=s(""),[y,k]=s(!1),[R,x]=s({show:!1,message:"",type:"info"}),L=async()=>{try{const N=await _.auth.user.query();l(N?.email?N:null)}catch{l(null)}},D=async()=>{try{const[N,P]=await Promise.all([_.auth.configStatus.query(),_.auth.googleAuth.query()]);v(!!N.hasConfig),h(!!(P.hasCustomWorkerUrl||P.hasCustomClientId||P.hasClientSecret))}catch(N){console.error("Failed to fetch config status",N)}};G(()=>{(async()=>{r(!0),await Promise.all([L(),D()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await L(),window.history.replaceState(null,"",window.location.pathname))}catch{}r(!1)})();const P=O=>{O.origin===window.location.origin&&typeof O.data=="object"&&O.data!==null&&O.data.type==="GOOGLE_AUTH_SUCCESS"&&(l(O.data.user),window.location.reload())};return window.addEventListener("message",P),()=>window.removeEventListener("message",P)},[]);const w=async()=>{try{const N=await _.auth.googleLogin.mutate();if(N.authenticated){window.location.reload();return}if(N.url){if(typeof window.DangoBridge<"u"){window.location.href=N.url;return}const O=600,q=700,f=window.innerWidth/2-O/2,W=window.innerHeight/2-q/2;window.open(N.url,"GoogleAuth",`width=${O},height=${q},top=${W},left=${f}`)}else throw new Error("Auth URL not available")}catch{x({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},C=async()=>{try{await _.auth.logout.mutate(),l(null),x({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(N){console.error("Sign out failed",N),x({show:!0,message:"Failed to sign out.",type:"error"})}},A=async()=>{k(!0);try{await _.auth.saveGoogleAuth.mutate({workerUrl:a,clientId:g,clientSecret:d}),c(""),m(""),S(""),await D(),x({show:!0,message:"Custom auth saved. Restart may be required.",type:"success"})}catch{x({show:!0,message:"Failed to save override.",type:"error"})}finally{k(!1)}},U=async()=>{k(!0);try{await _.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),c(""),m(""),S(""),await D(),x({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{x({show:!0,message:"Failed to clear override.",type:"error"})}finally{k(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:u.sectionCard,children:[e("h3",{className:u.title,children:"Google Drive Sync"}),i?e("div",{className:u.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:i.name})," (",i.email,")"]}),e(T,{variant:"danger",onClick:C,children:"Sign Out"})]}):e("div",{className:u.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(T,{onClick:w,disabled:!o,children:"Sign in with Google"}),!o&&e("p",{className:u.warning,children:"Google sync is not configured on the server."})]}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",b?"(override active)":""]}),e("div",{className:u.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:u.label,children:"Worker URL (optional)"}),e("input",{className:u.input,value:a,onChange:N=>c(N.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:u.formGroup,children:[e("label",{className:u.label,children:"Client ID (optional)"}),e("input",{className:u.input,value:g,onChange:N=>m(N.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:u.formGroup,children:[e("label",{className:u.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:u.input,value:d,onChange:N=>S(N.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:u.actions,children:[e(T,{onClick:A,disabled:y,children:"Save override"}),e(T,{variant:"secondary",onClick:U,disabled:y,children:"Use dango defaults"})]})]}),e($,{isOpen:R.show,onClose:()=>x(N=>({...N,show:!1})),width:"sm",children:[e($.Body,{children:e("p",{children:R.message})}),e($.Actions,{children:e(T,{onClick:()=>x(N=>({...N,show:!1})),children:"OK"})})]})]})},ot="_sectionCard_1pqo4_1",lt="_settingItem_1pqo4_26",ct="_settingRow_1pqo4_31",dt="_modalOverlay_1pqo4_38",ut="_modal_1pqo4_38",ht="_modalActions_1pqo4_73",gt="_modalSecondary_1pqo4_79",mt="_modalPrimary_1pqo4_89",E={sectionCard:ot,settingItem:lt,settingRow:ct,modalOverlay:dt,modal:ut,modalActions:ht,modalSecondary:gt,modalPrimary:mt},pt={anime:{heading:"Watchlist Preferences",blurb:"Customize your experience when managing your watchlist and series entries.",skipKey:"skipRemoveConfirmation",ignoreKey:"ignoreAdultContent",listOnlyKey:"cwWatchlistOnly",skipLabel:"Skip confirmation when removing from watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in watchlist",listNoun:"watchlist",continueNoun:"continue watching",adultCountUrl:"/api/continue-watching/adult-count",purgeUrl:"/api/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["allContinueWatching"]]},manga:{heading:"Reading List Preferences",blurb:"Customize your experience when managing your reading list and manga entries.",skipKey:"mangaSkipRemoveConfirmation",ignoreKey:"mangaIgnoreAdultContent",listOnlyKey:"mangaCwWatchlistOnly",skipLabel:"Skip confirmation when removing from reading list",ignoreLabel:"Hide adult content from continue reading",listOnlyLabel:"Only show continue reading for manga in reading list",listNoun:"reading list",continueNoun:"continue reading",adultCountUrl:"/api/manga/continue-reading/adult-count",purgeUrl:"/api/manga/continue-reading/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue reading`,invalidateKeys:[["manga-continue-reading"]]},tv:{heading:"TV Watchlist Preferences",blurb:"Customize your experience when managing your TV watchlist and series entries.",skipKey:"tvSkipRemoveConfirmation",ignoreKey:"tvIgnoreAdultContent",listOnlyKey:"tvCwWatchlistOnly",skipLabel:"Skip confirmation when removing from TV watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in TV watchlist",listNoun:"TV watchlist",continueNoun:"continue watching",adultCountUrl:"/api/tv/continue-watching/adult-count",purgeUrl:"/api/tv/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["tv-continue-watching"]]},asmr:{heading:"Listening List Preferences",blurb:"Customize your experience when managing your listening list and work entries.",skipKey:"asmrSkipRemoveConfirmation",ignoreKey:"asmrIgnoreAdultContent",listOnlyKey:"asmrCwWatchlistOnly",skipLabel:"Skip confirmation when removing from listening list",ignoreLabel:"Hide adult content from continue listening",listOnlyLabel:"Only show continue listening for works in listening list",listNoun:"listening list",continueNoun:"continue listening",adultCountUrl:"/api/asmr/continue-listening/adult-count",purgeUrl:"/api/asmr/continue-listening/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue listening`,invalidateKeys:[["asmr-continue-listening"]]}},yt=(t,r)=>{if(t==null)return r;const i=String(t);return i==="true"||i==="1"?!0:i==="false"||i==="0"?!1:r},le=(t,r,i)=>{const[l,o]=s(r),[v,b]=s(!1),h=ne();return G(()=>{(async()=>{try{const g=await _.settings.getByKey.query({key:t});o(yt(g.value,r))}catch(g){console.error("Failed to fetch setting",g)}})()},[t,r]),{value:l,setValue:o,isUpdating:v,toggle:async()=>{if(v)return;b(!0);const c=!l;o(c);try{await _.settings.set.mutate({key:t,value:c});for(const g of i)h.invalidateQueries({queryKey:g})}catch(g){console.error("Error saving setting:",g),o(!c)}finally{b(!1)}}}},ft=()=>{const{contentType:t}=ce(),r=pt[t],[i,l]=s(!1),[o,v]=s(!0),[b,h]=s(!1),a=le(r.ignoreKey,!0,r.invalidateKeys),c=le(r.listOnlyKey,!1,r.invalidateKeys),[g,m]=s(null),[d,S]=s(!1),y=ne(),k=Ce();G(()=>{v(!0),(async()=>{try{const C=await _.settings.getByKey.query({key:r.skipKey});String(C.value)==="true"||String(C.value)==="1"?l(!0):l(!1)}catch(C){console.error("Failed to fetch setting",C)}finally{v(!1)}})()},[r.skipKey]);const R=async()=>{if(b)return;h(!0);const w=!i;l(w);try{await _.settings.set.mutate({key:r.skipKey,value:w})}catch(C){console.error("Error saving setting:",C),l(!w)}finally{h(!1)}},x=async()=>{if(!a.isUpdating){if(a.value)try{let w;if(t==="anime"?w=(await _.continueWatching.adultCount.query()).count:t==="manga"?w=(await _.mangaProgress.adultCount.query()).count:t==="asmr"?w=(await _.asmrProgress.adultCount.query()).count:w=(await _.tvProgress.adultCount.query()).count,typeof w=="number"&&w>0){m(w);return}}catch(w){console.error("Failed to fetch adult count",w)}a.toggle()}},L=()=>{m(null),a.toggle()},D=async()=>{if(!d){S(!0);try{let w;t==="anime"?w=(await _.continueWatching.purgeAdult.mutate()).removed:t==="manga"?w=(await _.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?w=(await _.asmrProgress.purgeAdult.mutate()).removed:w=(await _.tvProgress.purgeAdult.mutate()).removed,ie.success(r.purgeDoneText(w??0));for(const C of r.invalidateKeys)y.invalidateQueries({queryKey:C});t==="anime"&&y.invalidateQueries(k.continueWatching.pathFilter()),t==="manga"&&y.invalidateQueries(k.mangaProgress.pathFilter()),t==="asmr"&&y.invalidateQueries(k.asmrProgress.pathFilter()),t==="tv"&&y.invalidateQueries(k.tvProgress.pathFilter())}catch(w){console.error("Failed to purge adult entries",w),ie.error("Failed to remove adult entries")}finally{S(!1),m(null)}a.toggle()}};return o?e("div",{children:"Loading settings..."}):e("div",{className:E.sectionCard,children:[e("h3",{children:r.heading}),e("p",{children:r.blurb}),e("div",{className:E.settingItem,children:e("div",{className:E.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:r.skipLabel}),e(K,{isChecked:i,onChange:R,id:"skip-confirmation-toggle",disabled:b})]})}),e("div",{className:E.settingItem,children:e("div",{className:E.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:r.ignoreLabel}),e(K,{isChecked:a.value,onChange:x,id:"ignore-adult-toggle",disabled:a.isUpdating})]})}),e("div",{className:E.settingItem,children:e("div",{className:E.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:r.listOnlyLabel}),e(K,{isChecked:c.value,onChange:c.toggle,id:"cw-watchlist-only-toggle",disabled:c.isUpdating})]})}),g!==null&&e("div",{className:E.modalOverlay,onClick:()=>m(null),children:e("div",{className:E.modal,onClick:w=>w.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[g," adult ",g===1?"entry":"entries"," not in your"," ",r.listNoun," ",g===1?"is":"are"," currently hidden from"," ",r.continueNoun,". You can purge ",g===1?"it":"them"," from the database instead of showing ",g===1?"it":"them","."]}),e("div",{className:E.modalActions,children:[e("button",{type:"button",className:E.modalSecondary,onClick:L,disabled:d,children:"Show them"}),e("button",{type:"button",className:E.modalPrimary,onClick:D,disabled:d,children:d?"Purging...":`Purge ${g}`})]})]})})]})},vt="_sectionCard_jkggs_1",wt="_statsGrid_jkggs_26",bt="_statCard_jkggs_33",kt="_statLabel_jkggs_43",Ct="_statValue_jkggs_51",_t="_statMeta_jkggs_57",St="_statusBanner_jkggs_63",Nt="_statusSuccess_jkggs_74",Tt="_statusUpdating_jkggs_80",It="_statusError_jkggs_86",Rt="_sha_jkggs_92",xt="_settingItem_jkggs_99",Lt="_settingRow_jkggs_104",Dt="_settingTitle_jkggs_111",Pt="_settingSubtitle_jkggs_117",At="_actionsRow_jkggs_124",I={sectionCard:vt,statsGrid:wt,statCard:bt,statLabel:kt,statValue:Ct,statMeta:_t,statusBanner:St,statusSuccess:Nt,statusUpdating:Tt,statusError:It,sha:Rt,settingItem:xt,settingRow:Lt,settingTitle:Dt,settingSubtitle:Pt,actionsRow:At},Ot=()=>{const[t,r]=s(null),[i,l]=s(!0),[o,v]=s(!1),[b,h]=s(!1),a=H(null),c=async()=>{try{const y=await _.settings.offlineDbInfo.query();return r(y),y}catch(y){console.error("Failed to fetch offline DB info:",y)}finally{l(!1)}return null};G(()=>(c(),()=>{a.current&&window.clearInterval(a.current)}),[]),G(()=>{t?.isRefreshing?a.current||(a.current=window.setInterval(async()=>{const y=await c();y&&!y.isRefreshing&&a.current&&(window.clearInterval(a.current),a.current=null)},2e3)):a.current&&(window.clearInterval(a.current),a.current=null)},[t?.isRefreshing]);const g=async()=>{if(!t||o)return;const y=!t.autoUpdateEnabled;v(!0),r({...t,autoUpdateEnabled:y});try{await _.settings.setOfflineDbAutoUpdate.mutate({enabled:y})}catch(k){console.error("Failed to update auto update setting:",k),r({...t,autoUpdateEnabled:!y})}finally{v(!1)}},m=async()=>{if(!(t?.isRefreshing||b)){h(!0);try{await _.settings.triggerOfflineDbUpdate.mutate(),r(y=>y?{...y,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(y){console.error("Failed to trigger offline DB update:",y)}finally{h(!1)}}},d=y=>{if(!y)return"Never";try{return new Date(y).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return y}},S=t?.isRefreshing||b;return e("div",{className:I.sectionCard,children:[e("h3",{children:"Offline Metadata Database"}),e("p",{children:"Local MAL to AniList ID map used for instant imports and metadata enrichment without hitting rate-limited APIs. Updates automatically every Saturday in the background."}),e("div",{className:I.statsGrid,children:[e("div",{className:I.statCard,children:[e("span",{className:I.statLabel,children:"MAL Mapped"}),e("span",{className:I.statValue,children:i?"—":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:I.statCard,children:[e("span",{className:I.statLabel,children:"Release"}),e("span",{className:I.statMeta,children:i?"—":t?.releaseTag??"Never"})]}),e("div",{className:I.statCard,children:[e("span",{className:I.statLabel,children:"Last Checked"}),e("span",{className:I.statMeta,children:i?"—":d(t?.lastCheckedAt??null)})]}),e("div",{className:I.statCard,children:[e("span",{className:I.statLabel,children:"Last Updated"}),e("span",{className:I.statMeta,children:i?"—":d(t?.lastUpdatedAt??null)})]})]}),t?.lastMessage&&e("div",{className:`${I.statusBanner} ${t.lastStatus==="failed"?I.statusError:t.lastStatus==="updating"?I.statusUpdating:I.statusSuccess}`,children:[e("span",{children:t.lastMessage}),t.contentSha256&&e("span",{className:I.sha,children:["sha:",t.contentSha256.slice(0,12)]})]}),e("div",{className:I.settingItem,children:e("div",{className:I.settingRow,children:[e("div",{children:[e("span",{className:I.settingTitle,children:"Weekly Automatic Updates (Saturdays)"}),e("div",{className:I.settingSubtitle,children:"Download and index new database releases in the background. Catches up on startup if the server was offline."})]}),e(K,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:g,disabled:i||o})]})}),e("div",{className:I.actionsRow,children:e(T,{onClick:m,disabled:i||S,children:S?"Updating Database...":"Update Offline Database Now"})})]})},Mt="_sectionCard_1g4qx_1",Gt="_dangerCard_1g4qx_26",Ut="_status_1g4qx_34",Et="_warningText_1g4qx_40",$t="_ackLabel_1g4qx_44",Q={sectionCard:Mt,dangerCard:Gt,status:Ut,warningText:Et,ackLabel:$t},zt=()=>{const t=ne(),[r,i]=s(!1),[l,o]=s(!1),[v,b]=s(!1),[h,a]=s(""),c=()=>{o(!1),a(""),i(!0)},g=()=>{v||(i(!1),o(!1))},m=async()=>{if(!(!l||v)){b(!0),a("");try{const d=await fetch("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),S=await d.json();if(!d.ok)throw new Error(S.error||"Failed to clear database");const y=S.deleted,k=S.deletedManga,R=S.deletedTv,x=S.deletedAsmr,L=Object.values(y).reduce((A,U)=>A+(U||0),0)+Object.values(k??{}).reduce((A,U)=>A+(U||0),0)+Object.values(R??{}).reduce((A,U)=>A+(U||0),0)+Object.values(x??{}).reduce((A,U)=>A+(U||0),0),D=(k?.manga_library??0)+(k?.manga_progress??0),w=(R?.tv_library??0)+(R?.tv_progress??0),C=(x?.asmr_library??0)+(x?.asmr_progress??0);a(`Library cleared — ${y.watchlist??0} watchlist entries, ${D} manga rows, ${w} TV rows, ${C} ASMR rows and ${L} total rows removed.`),t.invalidateQueries({queryKey:["watchlist"]}),t.invalidateQueries({queryKey:["allContinueWatching"]}),t.invalidateQueries({queryKey:["manga-library"]}),t.invalidateQueries({queryKey:["manga-continue-reading"]}),t.invalidateQueries({queryKey:["tv-library"]}),t.invalidateQueries({queryKey:["tv-continue-watching"]}),t.invalidateQueries({queryKey:["asmr-library"]}),t.invalidateQueries({queryKey:["asmr-continue-listening"]}),i(!1)}catch(d){a(d.message)}finally{b(!1),o(!1)}}};return e("div",{className:`${Q.sectionCard} ${Q.dangerCard}`,children:[e("h3",{children:"Danger Zone"}),e("p",{children:"Permanently delete your library (watchlist, watched episodes, queue, cached show metadata, manga reading list and reading progress, TV watchlist and watch progress, ASMR listening list and listening progress) to start fresh. Your settings, sync state and the offline metadata cache are preserved."}),e(T,{variant:"danger",onClick:c,children:"Clear Library Data"}),h&&e("p",{className:Q.status,children:h}),e($,{isOpen:r,onClose:g,title:"Clear library data?",width:"sm",children:[e($.Body,{children:[e("p",{className:Q.warningText,children:"This permanently deletes everything in your library. It acts on the active database (dev or prod, per server config) and cannot be undone. Settings, sync state and the offline metadata cache are kept."}),e("label",{className:Q.ackLabel,children:[e("input",{type:"checkbox",checked:l,onChange:d=>o(d.target.checked),disabled:v}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e($.Actions,{children:[e(T,{variant:"secondary",onClick:g,disabled:v,children:"Cancel"}),e(T,{variant:"danger",onClick:m,disabled:!l||v,children:v?"Clearing...":"Yes, delete everything"})]})]})]})},qt=()=>{const[t,r]=s(""),[i,l]=s([]),[o,v]=s(null),[b,h]=s(!0),[a,c]=s({show:!1,message:"",type:"info"}),g=async()=>{try{h(!0);const S=await(await fetch("/api/auth/settings/rclone")).json();r(S.remote||""),l(S.availableRemotes||[]),v(S.activeRemote||null)}catch(d){console.error("Failed to fetch Rclone settings",d)}finally{h(!1)}};G(()=>{g()},[]);const m=async()=>{try{if((await fetch("/api/auth/settings/rclone",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({remote:t})})).ok)c({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),g();else throw new Error("Failed to save")}catch{c({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return b?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:u.sectionCard,children:[e("h3",{className:u.title,children:"Rclone Cloud Sync"}),e("p",{className:u.signIn,children:"Configure which Rclone remote to use for database synchronization."}),o?e("div",{className:u.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:o})]})}):e("p",{className:u.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:u.formGroup,children:[e("label",{className:u.label,children:"Remote Name"}),e("div",{className:u.inputWrapper,children:e("select",{className:u.select,value:t,onChange:d=>r(d.target.value),children:[e("option",{value:"",children:"(Disabled / None)"}),i.map(d=>e("option",{value:d,children:d},d)),t&&!i.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:u.warning,style:{marginTop:"12px"},children:[e("strong",{children:"Note:"})," You can choose which provider is active using the selector at the top of the page."]})]}),e("div",{className:u.actions,children:e(T,{onClick:m,children:"Save Rclone Settings"})}),e($,{isOpen:a.show,onClose:()=>c(d=>({...d,show:!1})),width:"sm",children:[e($.Body,{children:e("p",{children:a.message})}),e($.Actions,{children:e(T,{onClick:()=>c(d=>({...d,show:!1})),children:"OK"})})]})]})},Ft=()=>{const[t,r]=s(null),[i,l]=s(!0),o=async()=>{try{const c=await(await fetch("/api/auth/settings/sync")).json();r(c)}catch(a){console.error("Failed to fetch sync settings",a)}finally{l(!1)}};G(()=>{o()},[]);const v=async a=>{const c=a.target.value;try{const g=await fetch("/api/auth/settings/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({provider:c})});if(g.ok){const m=await g.json();r(d=>d?{...d,activeProvider:m.activeProvider}:null),await o(),X.success(`Sync provider updated to ${c==="default"?"Default Order":c}`)}else X.error("Failed to update sync provider")}catch{X.error("Error updating sync provider")}};if(i||!t)return null;const b=[{value:"default",label:"Default (Priority Based)"}];t.authenticatedProviders.github&&b.push({value:"github",label:"GitHub"}),t.authenticatedProviders.google&&b.push({value:"google",label:"Google Drive"}),t.authenticatedProviders.rclone&&b.push({value:"rclone",label:"Rclone"}),b.push({value:"none",label:"None (Local Only)"});const h=a=>a==="none"?"Local Only (No Sync)":a==="google"?"Google Drive":a==="github"?"GitHub":a==="rclone"?"Rclone":a;return e("div",{className:p.sectionCard,children:[e("h3",{children:"Active Sync Provider"}),e("p",{children:'Choose which provider to use for synchronization. "Default" uses the first available provider you are logged into.'}),e("div",{style:{marginBottom:"1.5rem",padding:"0.75rem",background:"rgba(255, 255, 255, 0.03)",borderRadius:"var(--radius-md)",borderLeft:"4px solid var(--accent)",fontSize:"var(--font-size-sm)"},children:["Current Status:"," ",e("strong",{style:{color:"var(--accent-light)",textTransform:"capitalize"},children:h(t.actualActiveProvider)})]}),e("div",{className:p.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:t.activeProvider,onChange:v,style:{padding:"0.5rem",borderRadius:"var(--radius-md)",background:"rgba(255, 255, 255, 0.05)",color:"var(--text-primary)",border:"1px solid var(--glass-border)",fontSize:"var(--font-size-sm)",minWidth:"220px",outline:"none",cursor:"pointer"},children:b.map(a=>e("option",{value:a.value,children:a.label},a.value))})]})]})};function Kt(){return"javascript:"+encodeURIComponent(`(function(){
2
- if(!/(^|\\.)discord\\.com$/.test(location.hostname)){alert('Dango: use this bookmarklet while on discord.com');return}
3
- var t=null;
4
- try{
5
- window.webpackChunkdiscord_app.push([[Symbol()],{},function(req){
6
- if(!req.c)return;
7
- var ms=Object.values(req.c);
8
- for(var i=0;i<ms.length;i++){var m=ms[i];
9
- try{
10
- if(!m.exports||m.exports===window)continue;
11
- if(typeof m.exports.getToken==='function'){var x=m.exports.getToken();if(x){t=x;return}}
12
- for(var k in m.exports){try{var ex=m.exports[k];if(ex&&typeof ex.getToken==='function'&&ex[Symbol.toStringTag]!=='IntlMessagesProxy'){var y=ex.getToken();if(y){t=y;return}}}catch(e1){}}
13
- }catch(e2){}}
14
- }]);
15
- window.webpackChunkdiscord_app.pop();
16
- }catch(e3){}
17
- if(!t){alert('Dango: could not grab your token. Make sure you are logged in to Discord in this tab, then run the bookmarklet again.');return}
18
- function copyFallback(){var a=document.createElement('textarea');a.value=t;a.style.position='fixed';a.style.opacity='0';document.body.appendChild(a);a.select();try{document.execCommand('copy')}catch(e4){}document.body.removeChild(a)}
19
- var done=function(){window.close();setTimeout(function(){if(!window.closed){alert('Dango: token copied to clipboard! Could not close this tab, so just close it, go back to Dango Settings, paste the token and press Save.')}},250)};
20
- if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t).then(done,function(){copyFallback();done()})}else{copyFallback();done()}
21
- })()`)}const jt=()=>{const t=ve(Kt,[]);return e("div",{style:{marginTop:"0.9rem",paddingTop:"0.9rem",borderTop:"1px dashed var(--border-color)"},children:[e("h4",{style:{margin:"0 0 0.35rem",fontSize:"0.95rem"},children:"Grab the token automatically (bookmarklet)"}),e("p",{style:{margin:"0 0 0.6rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Set this up once and you never have to dig through DevTools: the bookmarklet copies your Discord token to the clipboard and closes the Discord tab — then you just paste it above and press Save."}),e("ol",{style:{margin:"0 0 0.75rem",paddingLeft:"1.25rem",fontSize:"0.85rem",color:"var(--text-secondary)",display:"grid",gap:"0.3rem"},children:[e("li",{children:["Drag the ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," ","button below onto your bookmarks bar (press ",e("kbd",{children:"Ctrl"}),"+",e("kbd",{children:"Shift"}),"+",e("kbd",{children:"B"})," ","first if the bar is hidden)."]}),e("li",{children:["Click ",e("strong",{style:{color:"var(--text-primary)"},children:"Open Discord"})," and log in (skip this if you are already logged in)."]}),e("li",{children:["On the Discord tab, click the"," ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," bookmark. The token lands in your clipboard and the tab closes on its own — come back here, paste it above and press ",e("strong",{children:"Save"}),"."]})]}),e("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("a",{href:t,onClick:l=>{l.preventDefault(),alert("Drag this button onto your bookmarks bar instead of clicking it, then click it while you are on discord.com.")},title:"Drag me to your bookmarks bar",draggable:!0,style:{display:"inline-flex",alignItems:"center",padding:"0.4rem 0.8rem",borderRadius:"999px",border:"1px dashed var(--accent)",background:"var(--bg-secondary)",color:"var(--text-primary)",fontSize:"0.85rem",textDecoration:"none",cursor:"grab",userSelect:"none"},children:[e(Y,{name:"bookmark",style:{marginRight:"0.45rem",color:"var(--accent)"}}),"Dango Token Grabber"]}),e("a",{className:"btn btn-secondary btn-sm",href:"https://discord.com/channels/@me",target:"_blank",rel:"noopener noreferrer",children:"Open Discord"}),e(T,{variant:"ghost",size:"sm",onClick:async()=>{try{await navigator.clipboard.writeText(t),alert('Bookmarklet code copied. Create a new bookmark on your bookmarks bar, name it "Dango Token" and paste the code as its URL.')}catch{alert(`Could not copy automatically. Right-click the "Dango Token Grabber" button and choose "Copy link address" instead, then paste that into a new bookmark's URL.`)}},children:"Copy code"})]}),e("p",{style:{margin:"0.5rem 0 0",fontSize:"0.75rem",color:"var(--text-tertiary)"},children:`"Copy code" is a fallback for browsers that won't drag bookmarklets: create any bookmark, then paste the copied code as its URL.`})]})},Ht="_sectionCard_1ag4p_1",Wt="_settingItem_1ag4p_25",Bt="_field_1ag4p_30",Vt="_input_1ag4p_43",Qt="_actions_1ag4p_63",Yt="_status_1ag4p_69",F={sectionCard:Ht,settingItem:Wt,field:Bt,input:Vt,actions:Qt,status:Yt},Jt=()=>{const[t,r]=s(!1),[i,l]=s(""),[o,v]=s(""),[b,h]=s(!0),[a,c]=s(!1),[g,m]=s("");G(()=>{(async()=>{try{const x=await(await fetch("/api/auth/app-status")).json();r(x.hasPassword)}catch{console.error("Failed to fetch LAN auth status")}finally{h(!1)}})()},[]);const d=async()=>{if(m(""),i!==o){m("Passwords do not match");return}if(i.length<4){m("Password must be at least 4 characters");return}c(!0);try{const k=await fetch("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:i})}),R=await k.json();if(!k.ok){m(R.error||"Failed to update password");return}r(R.hasPassword),l(""),v(""),m(R.hasPassword?"Password set successfully":"Password removed")}catch{m("Network error")}finally{c(!1)}},S=async()=>{c(!0);try{const k=await fetch("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:""})}),R=await k.json();if(!k.ok){m(R.error||"Failed to remove password");return}r(!1),l(""),v(""),m("Password removed")}catch{m("Network error")}finally{c(!1)}},y=async()=>{c(!0);try{await fetch("/api/auth/app-logout",{method:"POST"}),m("Logged out"),window.location.reload()}catch{m("Logout failed")}finally{c(!1)}};return b?e("div",{className:F.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:F.sectionCard,children:[e("h3",{children:"LAN Lock"}),e("p",{children:"Require a password to access this instance from any device, including this one. Sessions persist across server restarts until logout or password change."}),e("div",{className:F.settingItem,children:[e("div",{className:F.field,children:[e("label",{htmlFor:"lan-password",children:"New Password"}),e("input",{id:"lan-password",type:"password",value:i,onChange:k=>l(k.target.value),placeholder:t?"Leave empty to keep current password":"Enter a password...",className:F.input})]}),e("div",{className:F.field,children:[e("label",{htmlFor:"lan-confirm-password",children:"Confirm Password"}),e("input",{id:"lan-confirm-password",type:"password",value:o,onChange:k=>v(k.target.value),placeholder:"Confirm password...",className:F.input})]}),e("div",{className:F.actions,children:[e(T,{variant:"primary",onClick:d,loading:a,disabled:a,children:t?"Update Password":"Set Password"}),t&&e(T,{variant:"danger",onClick:y,loading:a,disabled:a,children:"Logout"}),t&&e(T,{variant:"secondary",onClick:S,loading:a,disabled:a,children:"Remove Password"})]}),g&&e("p",{className:F.status,children:g})]})]})},Xt=()=>{const{theme:t,setTheme:r,loading:i}=_e();return e("div",{children:[e("h4",{style:{margin:"0 0 0.25rem",fontSize:"1rem"},children:"Palette"}),e("p",{style:{margin:"0 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Taro is the default. Pick a palette that suits you."}),e("div",{role:"radiogroup","aria-label":"Palette",style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(150px, 1fr))",gap:"0.6rem"},children:Se.map(l=>{const o=t===l.id;return e("button",{role:"radio","aria-checked":o,disabled:i,onClick:()=>r(l.id),style:{display:"flex",gap:"0.6rem",alignItems:"center",textAlign:"left",padding:"0.65rem 0.75rem",borderRadius:"10px",cursor:"pointer",background:o?"var(--accent-subtle)":"var(--bg-tertiary)",border:o?"1px solid var(--accent)":"1px solid var(--border-primary)",color:"var(--text-primary)"},children:[e("span",{"aria-hidden":!0,style:{width:26,height:26,borderRadius:"50%",flex:"none",background:l.swatch,border:"1px solid rgba(0,0,0,0.35)"}}),e("span",{style:{minWidth:0},children:[e("span",{style:{display:"block",fontSize:"0.85rem",fontWeight:700},children:l.label}),e("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-secondary)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:l.blurb})]})]},l.id)})})]})};function Zt({variant:t="info",children:r,className:i=""}){return e("div",{className:`alert alert-${t} ${i}`,children:r})}const ea={anime:"Watchlist",manga:"Reading List",tv:"TV Watchlist",asmr:"Listening List"},ia=()=>{const[t,r]=we(),{contentType:i}=ce(),l=t.get("tab"),[o,v]=s(l&&["general","sync","watchlist","database"].includes(l)?l:"general"),[b,h]=s(""),a=H(null),c=H(null),g=H(new Map),[m,d]=s({top:0,height:0,left:0,width:0}),{lowEndMode:S,setLowEndMode:y}=Ne(),{hasConsent:k,revoke:R}=Te(),[x,L]=s(Ie),[D,w]=s(!0),{data:C}=oe("discordRPCEnabled"),A=Re(),[U,N]=s(!0),{data:P}=oe("discordRPCHideMature"),[O,q]=s(""),[f,W]=s(null);G(()=>{_.discord.gatewayStatus.query().then(n=>{W(n),n.masked&&n.masked!=="none"&&q(n.masked)}).catch(()=>{})},[]),G(()=>{C!==void 0&&w(C==="true"||C===!0||C===null)},[C]),G(()=>{P!==void 0&&N(P==="true"||P===!0||P===null)},[P]);const de=n=>{w(n),A.mutate({key:"discordRPCEnabled",value:String(n)})},ue=n=>{N(n),A.mutate({key:"discordRPCHideMature",value:String(n)})},he=n=>{L(n),localStorage.setItem(xe,String(n)),window.dispatchEvent(new CustomEvent(Le))};re.useEffect(()=>{document.title="Settings - dango"},[]),re.useEffect(()=>{const n=t.get("tab");n&&["general","sync","watchlist","database"].includes(n)&&v(n)},[t]);const J=n=>{v(n),r(n==="general"?{}:{tab:n})},B=ae(()=>{const n=g.current.get(o),M=c.current;if(n&&M){const j=M.getBoundingClientRect(),z=n.getBoundingClientRect(),V=window.matchMedia("(max-width: 900px)").matches;d(V?{top:z.top-j.top,height:z.height,left:z.left-j.left,width:z.width}:{top:z.top-j.top,height:z.height,left:0,width:0})}},[o]);be(()=>{B()},[o,B]),G(()=>{const n=()=>B();window.addEventListener("resize",n);let M=!1;return document.fonts?.ready&&document.fonts.ready.then(()=>{M||B()}),()=>{M=!0,window.removeEventListener("resize",n)}},[o,B]);const ge=()=>{h("Exporting databases...");const n=window.DangoBridge;if(n?.downloadFile){n.downloadFile("/api/backup-db","dango-backup.json"),setTimeout(()=>{h("Databases exported successfully!")},1500);return}const M=document.createElement("a");M.href="/api/backup-db",M.download="dango-backup.json",document.body.appendChild(M),M.click(),M.remove(),setTimeout(()=>{h("Databases exported successfully!")},1500)},me=async n=>{const M=n.target.files?.[0];if(!M)return;h("Importing databases...");const j=new FormData;j.append("dbfile",M);try{const z=await fetch("/api/restore-db",{method:"POST",body:j}),V=await z.json();if(z.ok){const se=Array.isArray(V.restored)?V.restored.join(", "):null;h(se?`Databases imported successfully (${se})!`:"Database imported successfully!"),setTimeout(()=>window.location.reload(),2e3)}else h(`Import failed: ${V.error}`)}catch{h("Import failed: An unexpected error occurred.")}finally{n.target.value=""}},pe=()=>{a.current?.click()},ye=()=>{switch(o){case"general":return e("div",{className:p.tabContent,children:e("div",{className:p.sectionCard,children:[e("h3",{children:"Appearance & Preferences"}),e("p",{children:"Configure how titles are displayed and other general preferences."}),e("div",{className:p.settingItem,children:e(De,{})}),e("div",{className:p.settingItem,style:{marginTop:"1.5rem"},children:e(Xt,{})}),e("div",{className:p.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:p.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Low End Mode"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Disables animations and heavy visual effects for better performance on older hardware."})]}),e(K,{isChecked:S,onChange:n=>y(n.target.checked),id:"low-end-mode"})]})}),e("div",{className:p.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:p.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Virtual Keyboard"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Shows an on-screen keyboard when text search fields are focused."})]}),e(K,{isChecked:x,onChange:n=>he(n.target.checked),id:"virtual-keyboard-enabled"})]})}),e("div",{className:p.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:p.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Rich Presence"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Show your current anime and watch progress on your Discord profile status."})]}),e(K,{isChecked:D,onChange:n=>de(n.target.checked),id:"discord-rpc-enabled"})]})}),e("div",{style:{marginTop:"2rem"},children:e(Jt,{})}),D&&e("div",{className:p.settingItem,style:{marginTop:"1rem"},children:e("div",{className:p.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Hide Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Hide mature content (18+) from Discord Rich Presence."})]}),e(K,{isChecked:U,onChange:n=>ue(n.target.checked),id:"discord-hide-mature"})]})}),e("div",{className:p.settingItem,style:{marginTop:"1.5rem",background:"var(--bg-tertiary)",padding:"1rem",borderRadius:"8px",border:"1px solid var(--border-color)"},children:[e("div",{className:p.settingRow,children:e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Mobile Presence (Gateway)"}),e("p",{style:{margin:"0.25rem 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Paste your Discord authentication token to enable presence on mobile devices. If no token is saved, the default desktop Rich Presence is used. The token is stored locally in your configuration and never shared."})]})}),e(Zt,{variant:"warning",style:{marginTop:"1.25rem",paddingTop:"1.25rem"},children:[e("strong",{children:"Use at your own risk."})," This feature uses the Discord Gateway API with your user token, which violates Discord's Terms of Service. Discord may detect this usage and take action against your account, including phone number locks, temporary suspensions, or permanent bans. While the risk is generally low, it is not zero. Only use this if you understand and accept the risks."]}),e("div",{style:{marginTop:"0.75rem",display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("input",{type:"password",value:O,onChange:n=>q(n.target.value),placeholder:"Paste Discord token here...",style:{flex:"1 1 200px",padding:"0.5rem",borderRadius:"4px",border:"1px solid var(--border-color)",background:"var(--bg-primary)",color:"var(--text-primary)",fontFamily:"monospace",minWidth:0}}),e(T,{variant:"primary",size:"sm",onClick:async()=>{try{const n=await _.discord.gatewaySave.mutate({token:O});W({hasToken:!0,masked:n.masked,enabled:!0}),q(n.masked)}catch(n){alert(n instanceof Error?n.message:"Failed to save token")}},children:"Save"}),e(T,{variant:"secondary",size:"sm",onClick:async()=>{await _.discord.gatewayRemove.mutate().catch(()=>{}),q(""),W({hasToken:!1,masked:null,enabled:!1})},children:"Remove"})]}),f&&e("p",{style:{marginTop:"0.5rem",fontSize:"0.8rem",color:f.hasToken?"green":"var(--text-secondary)"},children:["Status:"," ",f.hasToken?`Token saved (${f.masked})`:"No token saved",f.enabled?" - Gateway active":""]}),e(jt,{})]}),k&&e("div",{className:p.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:p.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"You have previously agreed to view 18+ content. Toggle this off to re-enable the blur gate and filtering."})]}),e(K,{isChecked:!0,onChange:n=>{n.target.checked||(R(),window.location.reload())},id:"mature-content-enabled"})]})})]})});case"sync":return e("div",{className:p.tabContent,children:[e(Ft,{}),e(rt,{}),e(it,{}),e(qt,{})]});case"watchlist":return e("div",{className:p.tabContent,children:e(ft,{})});case"database":return e("div",{className:p.tabContent,children:[e("div",{className:p.sectionCard,children:[e("h3",{children:"Database Management"}),e("p",{children:"Download a backup of all databases (anime, manga, TV and ASMR) or restore from a backup file. Legacy single-file anime (.db) backups can still be restored."}),e("div",{className:p.controls,children:[e(T,{onClick:ge,children:"Backup Database"}),e(T,{variant:"secondary",onClick:pe,children:"Restore Database"})]}),e("input",{type:"file",ref:a,onChange:me,style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"},accept:".json,.db,application/octet-stream"}),b&&e("p",{className:p.status,children:b})]}),e(Ot,{}),e(zt,{})]});default:return null}};return e("div",{className:"page-container",children:[e("div",{className:p.settingsHeader,children:[e("h1",{className:p.pageTitle,children:"Settings"}),e("p",{className:p.pageSubtitle,children:"Manage your preferences and data synchronization"})]}),e("div",{className:p.settingsLayout,children:[e("aside",{className:p.sidebar,ref:c,children:[e("div",{className:p.sidebarIndicator,style:{top:m.top,height:m.height,left:m.left,...m.width?{width:m.width}:{}}}),e("button",{ref:n=>{n&&g.current.set("general",n)},className:`${p.sidebarItem} ${o==="general"?p.active:""}`,onClick:()=>J("general"),children:[e(Y,{name:"cog"})," ",e("span",{children:"General"})]}),e("button",{ref:n=>{n&&g.current.set("sync",n)},className:`${p.sidebarItem} ${o==="sync"?p.active:""}`,onClick:()=>J("sync"),children:[e(Y,{name:"cloud"})," ",e("span",{children:"Synchronization"})]}),e("button",{ref:n=>{n&&g.current.set("watchlist",n)},className:`${p.sidebarItem} ${o==="watchlist"?p.active:""}`,onClick:()=>J("watchlist"),children:[e(Y,{name:"list"})," ",e("span",{children:ea[i]})]}),e("button",{ref:n=>{n&&g.current.set("database",n)},className:`${p.sidebarItem} ${o==="database"?p.active:""}`,onClick:()=>J("database"),children:[e(Y,{name:"database"})," ",e("span",{children:"Database"})]})]}),e("main",{className:p.mainContent,children:e("div",{className:p.tabContent,children:ye()},o)})]})]})};export{ia as default};
@@ -1,4 +0,0 @@
1
- import{u as t,d as _,A as w,h as y,S as Pe,g as Kr,o as qr,p as Yr,a as Gr,T as xe,q as S}from"./vendor-core-DfaOB3Rn.js";import{u as Qr}from"./vendor-query-BBT5_sHx.js";import{g as cn,e as Xr,t as Ct,z as Zr,O as Jr,M as wn,B as Ue}from"./index-CFHNQtWr.js";import{I as V}from"./vendor-icons-DrybRNxP.js";import{S as es,U as ts,p as Rn,M as ns,D as mr,m as $n,k as rs,C as ss,a as os,b as as,c as an,u as is,d as ls,e as cs,j as ds,f as us,h as ms,l as hs,B as gs,i as An,F as fs,G as ps,H as cr,s as Mn,n as bs,o as vs,q as ys,r as _s,t as Je,A as Ss,v as Ts,E as Cs,y as ks,P as Es,w as Te,z as xs,R as Ns}from"./AvSyncCalibrator-DQb5AJBT.js";import{S as Is,O as Ln,a as Bs,A as ws,b as As}from"./OptionListMenu-C9D50WHH.js";import{u as Ms}from"./useProviders-Du7D_fOu.js";import{d as Ls,g as Ps,h as Rs,f as $s,e as Ds,j as Os,k as Fs}from"./useTvLibrary-DPO3DmuK.js";import{l as Vs,c as js}from"./hls-B2witrNg.js";import{u as Us}from"./useIsMobile-Dvx1uJ82.js";import{S as Ws}from"./SynopsisText-B3Sa5pRv.js";const zs="_fullscreenFlat_1xij1_1",Hs="_timeDisplay_1xij1_15",Ks="_bottomControls_1xij1_19",qs="_leftControls_1xij1_23",Ys="_rightControls_1xij1_24",Gs="_controlBtn_1xij1_28",Qs="_controlsOverlay_1xij1_47",Xs="_hidden_1xij1_67",Zs="_topControls_1xij1_73",Js="_backBtn_1xij1_93",eo="_videoTitleInfo_1xij1_113",to="_animeTitle_1xij1_119",no="_episodeLabel_1xij1_127",ro="_speedBoostBadge_1xij1_134",so="_progressBarContainer_1xij1_180",oo="_progressBar_1xij1_180",ao="_thumb_1xij1_199",io="_bufferedBar_1xij1_217",lo="_watchedBar_1xij1_227",co="_scrubbing_1xij1_252",uo="_timeBubble_1xij1_256",mo="_bottomControlsRow_1xij1_270",ho="_nextEpisodeBtn_1xij1_293",go="_active_1xij1_346",fo="_settingsPanel_1xij1_421",po="_settingsHeader_1xij1_440",bo="_settingsBackBtn_1xij1_448",vo="_settingsTitle_1xij1_466",yo="_settingsContent_1xij1_477",_o="_currentValue_1xij1_486",So="_menuItem_1xij1_501",To="_menuNote_1xij1_534",Co="_loadingOverlay_1xij1_547",ko="_loadingDots_1xij1_558",Eo="_dot_1xij1_563",xo="_bufferingOverlay_1xij1_592",No="_bufferingSpinner_1xij1_601",a={fullscreenFlat:zs,timeDisplay:Hs,bottomControls:Ks,leftControls:qs,rightControls:Ys,controlBtn:Gs,controlsOverlay:Qs,hidden:Xs,topControls:Zs,backBtn:Js,videoTitleInfo:eo,animeTitle:to,episodeLabel:no,speedBoostBadge:ro,progressBarContainer:so,progressBar:oo,thumb:ao,bufferedBar:io,watchedBar:lo,scrubbing:co,timeBubble:uo,bottomControlsRow:mo,nextEpisodeBtn:ho,active:go,settingsPanel:fo,settingsHeader:po,settingsBackBtn:bo,settingsTitle:vo,settingsContent:yo,currentValue:_o,menuItem:So,menuNote:To,loadingOverlay:Co,loadingDots:ko,dot:Eo,bufferingOverlay:xo,bufferingSpinner:No},Io=({player:o,visible:p,settingsOpen:W,onOpenSettings:F,onCloseSettings:G,hasSubtitles:R,isSubtitleActive:r,subtitles:B,onSubtitleChange:i,showNextEpisodeButton:ee,onNextEpisode:Q,isTheaterMode:$,onTheaterModeToggle:h,timeLabelRef:K})=>{const{state:m,refs:We,actions:D}=o,X=We.videoRef,Re=T=>{const te=X.current;!te||isNaN(m.duration)||m.duration===0||(te.currentTime=T*m.duration)},$e=()=>{X.current&&(D.setIsScrubbing(!0),D.wasPlayingBeforeScrub.current=!X.current.paused,X.current.pause())},ze=T=>{const te=X.current;te&&m.duration&&(te.currentTime=T*m.duration)},He=()=>{D.setIsScrubbing(!1),D.wasPlayingBeforeScrub.current&&X.current?.play().catch(()=>{})},et=T=>{const te=X.current;te&&(te.volume=T,te.muted=T===0)},ae=()=>{if(r){i(-1);return}let T=null;try{T=localStorage.getItem("tvLastSubtitle")}catch{}i(Rn(B,{lastKey:T,enabled:!0}))},q=m.isMuted?t(V,{name:"volume-mute"}):m.volume<.5?t(V,{name:"volume-down"}):t(V,{name:"volume-up"});return t("div",{className:`${a.controlsOverlay} ${p?"":a.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:a.bottomControls,onClick:T=>T.stopPropagation(),children:[t(es,{classes:{container:a.progressBarContainer,scrubbing:a.scrubbing,timeBubble:a.timeBubble,bar:a.progressBar,buffered:a.bufferedBar,watched:a.watchedBar,thumb:a.thumb},videoRef:X,duration:m.duration,formatTime:cn,isScrubbing:m.isScrubbing,buffered:"full",onSeek:Re,onScrubStart:$e,onScrubMove:ze,onScrubEnd:He,timeLabelRef:K}),t("div",{className:a.bottomControlsRow,children:[t("div",{className:a.leftControls,children:[t("button",{className:a.controlBtn,onClick:D.togglePlay,"aria-label":m.isPlaying?"Pause":"Play",children:m.isPlaying?t(V,{name:"pause"}):t(V,{name:"play"})}),t(ts,{muted:m.isMuted,volume:m.volume,volumeIcon:q,buttonClassName:a.controlBtn,onToggleMute:D.toggleMute,onVolumeChange:et,onExpandedChange:T=>D.setShowVolumeSlider(T)}),t("span",{className:a.timeDisplay,ref:K,children:[cn(0)," / ",cn(m.duration)]})]}),t("div",{className:a.rightControls,children:[ee&&t("button",{className:a.nextEpisodeBtn,onClick:Q,title:"Play next episode",children:"Next EP"}),R&&t("button",{className:`${a.controlBtn} ${r?a.active:""}`,onClick:ae,"aria-label":r?"Turn subtitles off":"Turn subtitles on",children:t(V,{name:"closed-captioning"})}),t("button",{className:`${a.controlBtn} ${W?a.active:""}`,onClick:()=>W?G():F(),"aria-label":"Settings",children:t(V,{name:"cog"})}),t("button",{className:`${a.controlBtn} ${$?a.active:""}`,onClick:T=>{T.stopPropagation(),h()},title:$?"Exit Theater Mode":"Theater Mode","aria-label":$?"Exit Theater Mode":"Theater Mode",children:t(V,{name:"tv"})}),t("button",{className:a.controlBtn,onClick:D.toggleFullscreen,"aria-label":m.isFullscreen?"Exit Fullscreen":"Fullscreen",children:m.isFullscreen?t(V,{name:"compress"}):t(V,{name:"expand"})})]})]})]})})},ln=-6e4,Pn=6e4,dr=500,Bo=({classes:o,delayMs:p,onDelayChange:W})=>{const[F,G]=_(null),R=F??p,r=w(W);r.current=W;const B=w(p);B.current=p;const i=w(null);i.current=F,y(()=>{G(null)},[p]),y(()=>()=>{const $=i.current;$!==null&&$!==B.current&&r.current($)},[]);const ee=$=>{B.current=$,i.current=null,r.current($),G(null)},Q=$=>{const h=i.current??B.current,K=Math.max(ln,Math.min(Pn,h+$));ee(K)};return t(Pe,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:o.item,onClick:()=>Q(-dr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:o.item,onClick:()=>Q(dr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:o.item,onClick:()=>ee(0),disabled:R===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(ns,{label:"Subtitle timing",display:mr(R),min:ln,max:Pn,step:100,value:R,percent:(R-ln)/(Pn-ln)*100,onChange:$=>{const h=Math.round($);i.current=h,G(h)},onCommit:()=>{const $=i.current;$!==null&&ee($)}}),t("div",{className:o.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},wo=({view:o,onSelectView:p,onClose:W,player:F,onSubtitleStyleChange:G,streams:R,resolutionIdx:r,onResolutionChange:B,hasSubtitles:i,subtitles:ee,selectedSubtitle:Q,isSubtitleActive:$,onSubtitleChange:h,audioTracks:K,selectedAudioTrack:m,onAudioTrackChange:We,videoDelayEnabled:D,onVideoDelayToggle:X,videoDelayMs:Re,onVideoDelayChange:$e,onCalibrate:ze,subtitleDelayMs:He,onSubtitleDelayChange:et,ambientSettings:ae,onAmbientChange:q})=>{const{state:T}=F,te=()=>t(Pe,{children:[R.length>1&&t("button",{className:a.menuItem,onClick:()=>p("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:a.currentValue,children:R[r]?.quality||"Auto"})]}),i&&t("button",{className:a.menuItem,onClick:()=>p("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:a.currentValue,children:$?ee[Q]?.label||ee[Q]?.language:"Off"})]}),i&&t("button",{className:a.menuItem,onClick:()=>p("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:a.currentValue,children:[T.subtitleFontSize.toFixed(1),"x · ",T.subtitlePosition]})]}),i&&t("button",{className:a.menuItem,onClick:()=>p("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:a.currentValue,children:mr(He)})]}),K.length>0&&t("button",{className:a.menuItem,onClick:()=>p("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:a.currentValue,children:K[m]?.label||K[m]?.language})]}),t("button",{className:a.menuItem,onClick:()=>p("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:a.currentValue,children:D?`${Re}ms`:"Off"})]}),ae&&q&&t("button",{className:a.menuItem,onClick:()=>p("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:a.currentValue,children:ae.enabled?"On":"Off"})]})]}),Ce=()=>t(Ln,{classes:{item:a.menuItem,active:a.active},options:R.map((C,z)=>({key:String(z),label:C.quality,selected:z===r})),onSelect:C=>B(Number(C))}),Y=()=>t(Ln,{classes:{item:a.menuItem,active:a.active},options:[{key:"off",label:"Off",selected:!$},...ee.map((C,z)=>({key:String(z),label:C.label||C.language,selected:z===Q}))],onSelect:C=>h(C==="off"?-1:Number(C))}),ke=()=>t(Bs,{classes:{item:a.menuItem,active:a.active},values:{fontSize:T.subtitleFontSize,position:T.subtitlePosition,bgOpacity:T.subtitleBgOpacity,bgColor:T.subtitleBgColor,textColor:T.subtitleTextColor,edge:T.subtitleEdge,bold:T.subtitleBold},onChange:G}),A=()=>t(Bo,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},delayMs:He,onDelayChange:C=>et?.(C)}),De=()=>t(Ln,{classes:{item:a.menuItem,active:a.active},options:K.map((C,z)=>({key:String(z),label:C.label||C.language,selected:z===m})),onSelect:C=>We(Number(C))}),Ke=()=>t(ws,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},enabled:D,delayMs:Re,onToggle:C=>X?.(C),onDelayChange:C=>$e?.(C),onCalibrate:ze}),be=()=>ae&&q?t(As,{classes:{item:a.menuItem,active:a.active,note:a.menuNote},values:ae,onChange:q}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:C=>C.stopPropagation(),children:t(Is,{classes:{panel:a.settingsPanel,header:a.settingsHeader,backBtn:a.settingsBackBtn,title:a.settingsTitle,content:a.settingsContent},title:o==="main"?"Settings":o==="subtitle-style"?"Subtitle Style":o==="subtitle-timing"?"Subtitle Timing":o==="audio"?"Audio Track":o==="resolution"?"Resolution":o==="av-sync"?"A/V Sync":o==="ambient"?"Ambient Light":o.charAt(0).toUpperCase()+o.slice(1),onBack:()=>o==="main"?W():p("main"),children:[o==="main"&&te(),o==="resolution"&&Ce(),o==="subtitles"&&Y(),o==="subtitle-style"&&ke(),o==="subtitle-timing"&&A(),o==="audio"&&De(),o==="av-sync"&&Ke(),o==="ambient"&&be()]})})},Ao=({player:o,title:p,episodeLabel:W,audioTracks:F,selectedAudioTrack:G,onAudioTrackChange:R,subtitles:r,selectedSubtitle:B,onSubtitleChange:i,streams:ee,resolutionIdx:Q,onResolutionChange:$,onBack:h,children:K,videoDelayEnabled:m=!1,onVideoDelayToggle:We,videoDelayMs:D=0,onVideoDelayChange:X,onCalibrateAvSync:Re,subtitleDelayMs:$e=0,onSubtitleDelayChange:ze,showNextEpisodeButton:He=!1,onNextEpisode:et,isLoading:ae=!1,isTheaterMode:q,onTheaterModeToggle:T,ambientSettings:te,onAmbientChange:Ce})=>{const{state:Y,refs:ke,actions:A}=o,De=ke.videoRef,{subtitleFontSize:Ke,subtitlePosition:be,subtitleBgOpacity:C,subtitleBgColor:z,subtitleTextColor:dt,subtitleEdge:ie,subtitleBold:Oe}=Y,[Ne,Fe]=_(null),ut=w(null),[jt,kt]=_(0);y(()=>{const ye=De.current;if(!ye)return;const b=()=>kt(ye.clientHeight||0);b();const tt=new ResizeObserver(b);return tt.observe(ye),()=>tt.disconnect()},[De]);const ue=(ye,b)=>{try{localStorage.setItem(ye,String(b))}catch{}},ve=(ye,b)=>{switch(ye){case"fontSize":typeof b=="number"&&(A.setSubtitleFontSize(b),ue("subtitleFontSize",b));break;case"position":typeof b=="number"&&(A.setSubtitlePosition(b),ue("subtitlePosition",b));break;case"bgOpacity":typeof b=="number"&&(A.setSubtitleBgOpacity(b),ue("subtitleBgOpacity",b));break;case"bgColor":typeof b=="string"&&(A.setSubtitleBgColor(b),ue("subtitleBgColor",b));break;case"textColor":typeof b=="string"&&(A.setSubtitleTextColor(b),ue("subtitleTextColor",b));break;case"edge":(b==="shadow"||b==="outline"||b==="none")&&(A.setSubtitleEdge(b),ue("subtitleEdge",b));break;case"bold":typeof b=="boolean"&&(A.setSubtitleBold(b),ue("subtitleBold",b));break}};y(()=>{const ye="tv-player-subtitle-style";let b=document.getElementById(ye);b||(b=document.createElement("style"),b.id=ye,document.head.appendChild(b));const tt={fontSize:Ke,position:be,bgOpacity:C,bgColor:z,textColor:dt,edge:ie,bold:Oe},ne=De.current,It=$n(Ke,jt||ne?.clientHeight||720);if(b.textContent=rs({...tt,fontSize:It}),ne){const ft=()=>{const L=Number(be);return isNaN(L)?0:Math.max(0,Math.min(100,L))},v=(L,Z)=>{try{const de=L;de.snapToLines=!1,de.line=Z}catch{}},c=()=>{const L=It*16,Z=ne.videoHeight||ne.clientHeight||720,de=ne.videoWidth||ne.clientWidth||1280;return{step:L*1.3/Z*100,chars:Math.max(20,Math.floor(de/(L*.55)))}},ce=L=>{const Z=Math.max(0,Math.min(100,100-ft())),de=Array.from(L.activeCues??[]);if(de.length<=1){de.forEach(qe=>v(qe,Z));return}const{step:Ee,chars:zt}=c();let Ht=Z;for(let qe=de.length-1;qe>=0;qe--){const dn=String(de[qe].text??"").replace(/<[^>]*>/g,"").split(`
2
- `).reduce((At,Ye)=>At+Math.max(1,Math.ceil(Ye.length/zt)),0),me=Ht-dn*Ee;v(de[qe],Math.max(0,me)),Ht=me-Ee*.4}},re=()=>{const L=Math.max(0,Math.min(100,100-ft()));Array.from(ne.textTracks).forEach(Z=>{Z.cues&&(Array.from(Z.cues).forEach(de=>v(de,L)),Z.mode==="showing"&&ce(Z))})};re();const nt=L=>{const Z=L.target;Z.mode==="showing"&&ce(Z)},Bt=()=>{Array.from(ne.textTracks).forEach(L=>{L.removeEventListener("cuechange",nt),L.addEventListener("cuechange",nt)}),re()};Array.from(ne.textTracks).forEach(L=>{L.addEventListener("cuechange",nt)}),ne.textTracks.addEventListener("addtrack",Bt);const wt=Array.from(ne.querySelectorAll("track")),pt=()=>re();return wt.forEach(L=>L.addEventListener("load",pt)),()=>{Array.from(ne.textTracks).forEach(L=>{L.removeEventListener("cuechange",nt)}),ne.textTracks.removeEventListener("addtrack",Bt),wt.forEach(L=>L.removeEventListener("load",pt))}}},[Ke,be,C,z,dt,ie,Oe,B,r,De,jt]);const Et=r.length>0,mt=B>=0,M=()=>{Fe("main"),A.setShowControls(!0)},ht=()=>{Fe(null)},xt=Y.showControls||!!Ne,gt=t(as,{visible:xt,title:p,episode:W,onBack:h,classes:{overlay:a.controlsOverlay,hidden:a.hidden,top:a.topControls,backBtn:a.backBtn,titleInfo:a.videoTitleInfo,title:a.animeTitle,episode:a.episodeLabel}}),Ut=!ae&&!Y.isBuffering&&Y.duration>0?t(ss,{isPlaying:Y.isPlaying,onTogglePlay:A.togglePlay,onSkipBack:()=>A.seek(-10),onSkipForward:()=>A.seek(10)}):null,Wt=t(Io,{player:o,visible:xt,settingsOpen:!!Ne,onOpenSettings:M,onCloseSettings:ht,hasSubtitles:Et,isSubtitleActive:mt,subtitles:r,onSubtitleChange:i,showNextEpisodeButton:He,onNextEpisode:et,isTheaterMode:q,onTheaterModeToggle:T,timeLabelRef:ut}),Nt=Ne?t(wo,{view:Ne,onSelectView:Fe,onClose:ht,player:o,onSubtitleStyleChange:ve,streams:ee,resolutionIdx:Q,onResolutionChange:$,hasSubtitles:Et,subtitles:r,selectedSubtitle:B,isSubtitleActive:mt,onSubtitleChange:i,audioTracks:F,selectedAudioTrack:G,onAudioTrackChange:R,videoDelayEnabled:m,onVideoDelayToggle:We,videoDelayMs:D,onVideoDelayChange:X,onCalibrate:()=>{Fe(null),Re?.()},subtitleDelayMs:$e,onSubtitleDelayChange:ze,ambientSettings:te,onAmbientChange:Ce}):null,le=t(Pe,{children:[ae&&t("div",{className:a.loadingOverlay,"aria-hidden":"true",children:t("div",{className:a.loadingDots,children:[t("div",{className:a.dot}),t("div",{className:a.dot}),t("div",{className:a.dot})]})}),Y.isBuffering&&!ae&&t("div",{className:a.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:a.bufferingSpinner})}),Y.isSpeedBoostActive&&t("div",{className:a.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(V,{name:"forward",size:12})]})]});return t(os,{player:o,topBar:gt,centerControls:Ut,bottomBar:!ae&&Y.duration>0?Wt:null,settingsPanel:Nt,overlays:le,isInteracting:!!Ne,className:Y.isFullscreen?a.fullscreenFlat:"",children:K})},Mo=({servers:o,selectedServer:p,onServerSelect:W})=>o.length===0?null:t("div",{className:an.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:an.sourceButtons,children:o.map(F=>t("button",{className:`${an.sourceButton} ${p===F?an.active:""}`,onClick:()=>W(F),children:F},F))})]}),Lo=Kr.memo(Mo);function Po(o,p,W){const F=()=>{const R=Array.isArray(o.audioTracks)?o.audioTracks.length:0,r=W.getWant(),B=R>0?Math.min(Math.max(0,r),R-1):r;o.audioTrack=B,B!==r&&W.onResolve(B)},G=(R,r)=>{const B=W.getWant(),i=Array.isArray(o.audioTracks)?o.audioTracks.length:0;if(r.id!==B&&B>=0&&B<i){o.audioTrack!==B&&(o.audioTrack=B);return}W.onResolve(r.id)};return o.on(p.MANIFEST_PARSED,F),o.on(p.AUDIO_TRACK_SWITCHED,G),()=>{o.off(p.MANIFEST_PARSED,F),o.off(p.AUDIO_TRACK_SWITCHED,G)}}const Ro=/\b(SmartTV|SMART-TV|Tizen|Web0S|webOS|NetCast|HbbTV|AppleTV|CrKey|BRAVIA|AFT[A-Za-z]|Fire\s?TV|GoogleTV|Roku|VIDAA|DTV|PlayStation|Xbox|Opera TV|POV_TV)\b/i;function $o(){try{if(Ro.test(navigator.userAgent||""))return!0;const o=navigator.deviceMemory;if(typeof o=="number"&&o>0&&o<2)return!0}catch{}return!1}const Do="_page_y9mr4_1",Oo="_header_y9mr4_7",Fo="_pageTitle_y9mr4_11",Vo="_searchForm_y9mr4_21",jo="_searchInput_y9mr4_27",Uo="_searchBtn_y9mr4_42",Wo="_suggestions_y9mr4_58",zo="_suggestionPill_y9mr4_65",Ho="_statusMsg_y9mr4_81",Ko="_error_y9mr4_87",qo="_textOnly_y9mr4_91",Yo="_spinner_y9mr4_96",Go="_spin_y9mr4_96",Qo="_sourceLoader_y9mr4_101",Xo="_ringSpinner_y9mr4_107",Zo="_grid_y9mr4_125",Jo="_skeletonCard_y9mr4_131",ea="_skeletonThumb_y9mr4_136",ta="_skeletonLine_y9mr4_142",na="_shimmer_y9mr4_149",ra="_backBtn_y9mr4_169",sa="_meta_y9mr4_187",oa="_headerActions_y9mr4_195",aa="_watchlistBtn_y9mr4_202",ia="_active_y9mr4_220",la="_year_y9mr4_230",ca="_rating_y9mr4_235",da="_typeBadge_y9mr4_244",ua="_tv_y9mr4_252",ma="_movie_y9mr4_257",ha="_tvSeries_y9mr4_262",ga="_tvMiniSeries_y9mr4_267",fa="_overview_y9mr4_272",pa="_controls_y9mr4_279",ba="_controlLabel_y9mr4_287",va="_select_y9mr4_297",ya="_playerSection_y9mr4_308",_a="_video_y9mr4_312",Sa="_videoHidden_y9mr4_334",Ta="_delayCanvas_y9mr4_339",Ca="_delayCanvasActive_y9mr4_352",ka="_subtitleOverlay_y9mr4_356",Ea="_videoIframe_y9mr4_375",xa="_retryButton_y9mr4_383",Na="_sidebarSeason_y9mr4_398",Ia="_mobileSeasonRow_y9mr4_414",Ba="_sidebarPosterCard_y9mr4_428",wa="_sidebarPosterMeta_y9mr4_443",Aa="_providerSelectWrap_y9mr4_460",Ma="_genreRow_y9mr4_472",La="_genreChip_y9mr4_479",Pa="_metaRow_y9mr4_489",Ra="_detailGrid_y9mr4_498",$a="_detailItem_y9mr4_505",Da="_imdbLink_y9mr4_527",f={page:Do,header:Oo,pageTitle:Fo,searchForm:Vo,searchInput:jo,searchBtn:Uo,suggestions:Wo,suggestionPill:zo,statusMsg:Ho,error:Ko,textOnly:qo,spinner:Yo,spin:Go,sourceLoader:Qo,ringSpinner:Xo,grid:Zo,skeletonCard:Jo,skeletonThumb:ea,skeletonLine:ta,shimmer:na,backBtn:ra,meta:sa,headerActions:oa,watchlistBtn:aa,active:ia,year:la,rating:ca,typeBadge:da,tv:ua,movie:ma,tvSeries:ha,tvMiniSeries:ga,overview:fa,controls:pa,controlLabel:ba,select:va,playerSection:ya,video:_a,videoHidden:Sa,delayCanvas:Ta,delayCanvasActive:Ca,subtitleOverlay:ka,videoIframe:Ea,retryButton:xa,sidebarSeason:Na,mobileSeasonRow:Ia,sidebarPosterCard:Ba,sidebarPosterMeta:wa,providerSelectWrap:Aa,genreRow:Ma,genreChip:La,metaRow:Pa,detailGrid:Ra,detailItem:$a,imdbLink:Da},Oa=[],Fa=[];function ur({error:o,onRetry:p}){return t("div",{className:`${f.statusMsg} ${f.error}`,style:{flexDirection:"column",alignItems:"stretch",gap:8},children:t("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[t("span",{style:{flex:1},children:o}),t("button",{className:f.retryButton,onClick:p,children:"Retry"})]})})}const Za=()=>{const{id:o}=qr(),[p]=Yr(),W=w(p);W.current=p;const F=Gr(),G=Qr(),R=p.get("type"),[r,B]=_(null),[i,ee]=_(()=>parseInt(p.get("s")||"1",10)||1),[Q,$]=_([]),[h,K]=_(()=>parseInt(p.get("e")||"1",10)||1),[m,We]=_(()=>{try{return localStorage.getItem("tvProvider")||""}catch{return""}}),[D,X]=_([]),[Re,$e]=_(""),{options:ze,isFallback:He,isLoading:et}=Ms(),ae=xe(()=>ze.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.value,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[ze]),q=He||ae.length===0?Oa:ae,T=q.filter(e=>e.tier==="direct"),te=q.filter(e=>e.tier==="embed"),[Ce,Y]=_(!1),[ke,A]=_(""),[De,Ke]=_([]),[be,C]=_(0),[z,dt]=_([]),[ie,Oe]=_(-1),[Ne,Fe]=_(0),[ut,jt]=_(""),[kt,ue]=_(""),[ve,Et]=_(()=>{try{return localStorage.getItem("tvServer")||""}catch{return""}}),mt=xe(()=>q.find(e=>e.id===m),[q,m]),M=mt?.tier==="embed",[ht,xt]=_([]),[gt,Ut]=_(""),[Wt,Nt]=_(!1),le=xe(()=>ht.length>0?ht:mt?.servers??[],[ht,mt]),ye=xe(()=>gt?[...le,"Embed"]:le,[le,gt]),b=Wt&&!!gt,tt=b?gt:"",ne=w([]);y(()=>{ne.current=D},[D]);const It=w(be);y(()=>{It.current=be},[be]);const ft=w(ie);y(()=>{ft.current=ie},[ie]);const v=is({skipIntervals:Fa}),c=v.refs.videoRef,ce=w(null),re=w([]),nt=w(null),Bt=w(null),{videoDelayMs:wt,videoDelayEnabled:pt,setDelayEnabled:L,handleVideoDelayChange:Z,isCalibrating:de,testClipActive:Ee,stopCalibration:zt,openAvSyncCalibrator:Ht,cancelAvSyncCalibrator:qe,applyAvSyncCalibrator:Dn,toggleTestClip:dn,calibReturnRef:me,effectiveVideoDelayMs:At}=ls(c),[Ye,hr]=_(()=>{try{const e=Number(localStorage.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),un=w(Ye);un.current=Ye;const gr=S(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(un.current!==n){un.current=n,hr(n);try{localStorage.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);cs({videoRef:c,canvasRef:nt,delayMs:At,enabled:pt});const mn=pt,_e=mn||Ye!==0,{settings:hn,update:fr}=ds(),gn=w(_e);gn.current=_e;const fn=S(()=>{if(!gn.current)return;const e=c.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[c]),{hasConsent:Mt,grant:pr}=Xr(),Lt=w("");Lt.current||(Lt.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const g=R==="movie",Kt=o?Ls(R||"tv",o):"",j=Kt,On=Ps(),qt=Rs(),{toggle:Fn,bookmarkedIds:br,pending:vr}=$s(),{data:Vn}=Ds(r?Kt:void 0),Yt=Vn?!!Vn.inLibrary:Kt?br.has(Kt):!1,yr=S(()=>{!r||!o||Fn({tmdbId:Number(o),mediaType:R||"tv",title:r.title,poster:r.poster,year:r.year,adult:r.adult})},[r,o,R,Fn]),{data:rt,isFetched:jn,isPending:Un}=Os(j||void 0,i,h),Gt=xe(()=>Q.map(e=>e.episode_number).sort((e,n)=>e-n),[Q]),st=Gt.indexOf(h),pn=st>0?Gt[st-1]:null,x=st>=0&&st<Gt.length-1?Gt[st+1]:null,Qt=xe(()=>(r?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[r]),Se=xe(()=>{if(g||x!=null)return null;const e=Qt.indexOf(i);return e>=0&&e<Qt.length-1?Qt[e+1]:(r?.number_of_seasons??0)>i?i+1:null},[g,x,Qt,i,r?.number_of_seasons]),Wn=rt?.currentTime??0,zn=rt?.duration??0,bn=rt?.completed===!0||rt?.completed===1||An(Wn,zn),[Ie,Ve]=_(!1),Be=w(!1),vn=w(null),Pt=w(null);y(()=>{Be.current=!1,Pt.current=null,Ve(!1)},[j,i,h]);const[we,Xt]=_(!1),[bt,Hn]=_(0),[ot,Kn]=_(!1),[Ge,at]=_(!1),[_r,yn]=_(!1),[Sr,qn]=_(""),[Zt,Tr]=_(!1),[Cr,_n]=_(!1),{isTheaterMode:Ae,toggleTheaterMode:Sn,handleLayoutClick:kr}=us();y(()=>{const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&Sn()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[Sn]),ms(v,(D.length>0||kt!=="")&&!Ae&&!we&&!Ie&&!Ge);const Er=Us(),[vt,xr]=_(hs),Nr=S(e=>{xr(e),gs(e)},[]),he=w(!1),it=w(null),Tn=w(0),Yn=w(!1),Gn=w(0),se=w(null),Rt=w(""),Ir=cr(Wn,zn),$t=!he.current&&!Be.current&&(we||Ie||Ge||bn||Ir),yt=w($t);yt.current=$t;const _t=w(!1);y(()=>{_t.current=ot},[ot]);const Qe=S((e,n)=>{if(!j||!n||n<30)return;const s=An(e,n),l=s?n:e;Math.abs(l-Tn.current)<10&&!s||(Tn.current=l,On.mutate({mediaId:j,season:i,episode:h,currentTime:Math.floor(l),duration:Math.floor(n),completed:s,title:r?.title??null,poster:r?.poster??null,backdrop:r?.backdrop??null,year:r?.year??null,overview:r?.overview??null,tmdbId:r?.id??null,mediaType:R||"tv",adult:r?.adult?1:0}))},[j,i,h,On,r,R]),Me=S((e,n)=>{zt();const s=new URLSearchParams(p);s.set("type",p.get("type")||"tv"),s.set("s",String(e)),s.set("e",String(n)),F(`${window.location.pathname}?${s.toString()}`)},[p,F,zt]),Dt=S(()=>{const e=c.current;if(!e||g||x==null){yn(!1);return}const n=e.duration||0,s=e.currentTime||0;yn(n>0&&s/n>=.8)},[g,x,c]),Jt=S((e,n)=>["tv-sources",m,g?"movie":"tv",o,e,n,ve],[m,g,o,ve]),en=S(async(e,n)=>{if(!r||!o||!m)return{valid:!1,sources:[]};const s=g?"movie":"tv",l=await Ct.tv.sources.query({provider:m,type:s,tmdbId:String(o),season:e,episode:n,title:r.title||"",year:r.year||"",totalSeasons:String(r.number_of_seasons||1),imdbId:r.imdb_id||"",...le.length>0&&ve?{server:ve}:{}});return{valid:"valid"in l?l.valid:!1,error:"error"in l?l.error:void 0,sources:l.sources,referer:"referer"in l?l.referer:void 0,audioTracks:l.audioTracks,subtitles:"subtitles"in l?l.subtitles:void 0,servers:"servers"in l?l.servers:void 0,embedUrl:"embedUrl"in l?l.embedUrl:void 0}},[r,o,m,g,le,ve]),Qn=S(()=>{if(g||!r||!o||!m||M||x==null)return;const e=Jt(i,x);G.getQueryState(e)?.status!=="success"&&G.prefetchQuery({queryKey:e,queryFn:()=>en(i,x),staleTime:300*1e3,gcTime:1800*1e3})},[g,r,o,m,M,x,i,G,Jt,en]),Br=S(()=>{if(Ee)return;Dt();const e=c.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&Qn(),it.current&&clearTimeout(it.current),it.current=setTimeout(()=>{Qe(e.currentTime,e.duration||0)},5e3))},[Qe,c,Ee,Dt,Qn]),wr=S(()=>{const e=c.current;if(!e||!r)return;it.current&&clearTimeout(it.current),Qe(e.currentTime,e.duration||0),Yn.current=!0;const n=fs({seekInduced:Date.now()-Gn.current<ps,autoplayEnabled:vt,hasNext:!g&&x!=null,isFinal:g||x==null});n==="advance"&&x!=null?(K(x),Me(i,x)):n==="prompt-next"?(Be.current=!1,he.current=!0,Ve(!0)):n==="prompt-complete"&&(qn(g?r.title:`${r.title} — Season ${i}`),at(!0),Be.current=!0,he.current=!0)},[g,r,i,x,vt,Qe,Me,c]),Ar=S(()=>{Yn.current=!1,v.actions.onPlay()},[v.actions]),Mr=S(()=>{v.actions.onPause();const e=c.current;e&&!e.ended&&Qe(e.currentTime,e.duration||0)},[v.actions,Qe,c]),Lr=S(()=>{v.actions.onLoadedMetadata();const e=c.current;if(e){try{const n=parseFloat(localStorage.getItem("playerVolume")||"");isNaN(n)||(e.volume=Math.max(0,Math.min(1,n))),e.muted=localStorage.getItem("playerMuted")==="true"}catch{}if(se.current!=null&&se.current>0){try{e.currentTime=se.current}catch{}se.current=null}Dt()}},[v.actions,c,Dt]),St=S(()=>{const e=c.current;if(e&&se.current!=null&&se.current>0){try{e.currentTime=se.current}catch{}se.current=null}},[c]),Pr=S(()=>{bt>0&&(se.current=bt);const e=c.current;if(e&&bt>0){try{e.currentTime=bt,se.current=null}catch{}e.play().catch(()=>{})}Xt(!1),he.current=!0},[bt,c]),Xn=S(()=>{se.current=null;const e=c.current;e&&(e.currentTime=0,e.play().catch(()=>{})),Xt(!1),he.current=!0},[c]),Rr=S(()=>{Be.current=!0,Ve(!1),he.current=!0},[]),$r=S(()=>{Be.current=!0,Ve(!1),he.current=!0,se.current=null;const e=c.current;if(e){try{e.currentTime=0}catch{}e.play().catch(()=>{})}},[c]),Zn=S(()=>{x!=null&&(Be.current=!0,Ve(!1),he.current=!0,K(x),Me(i,x))},[x,i,Me]),Jn=S(()=>{Se!=null&&(Be.current=!0,Ve(!1),at(!1),he.current=!0,ee(Se),K(1),Me(Se,1))},[Se,Me]),Dr=S(async()=>{if(j)try{await qt.mutateAsync({id:j,status:"Completed"}),at(!1),Ve(!1),F("/")}catch{}},[j,qt,F]);y(()=>{he.current=!1,vn.current=null,Xt(!1),yn(!1),Hn(0),Kn(!1),_t.current=!1,se.current=null,Rt.current=`${j}:${i}:${h}`,Tn.current=0},[j,i,h]),y(()=>{jn&&(Kn(!0),_t.current=!0)},[jn,j,i,h]),y(()=>{if(!rt||he.current)return;const e=`${j}:${i}:${h}`;if(vn.current===e)return;vn.current=e;const n=rt,s=n.currentTime??0,l=n.duration??0;cr(s,l)&&(Hn(s),Xt(!0))},[rt,j,i,h]),y(()=>{if(!ot||he.current||Be.current||we||Ge||Ie)return;const e=`${j}:${i}:${h}`;if(Pt.current!==e){if(!bn){Un||(Pt.current=e);return}if(g){Pt.current=e,Ve(!0);return}if(!(!r||st<0||Q.length===0)){if(Pt.current=e,x==null&&Se==null){r&&Q.length>0&&(qn(`${r.title} — Season ${i}`),at(!0),Be.current=!0,he.current=!0);return}Ve(!0)}}},[ot,bn,Un,we,Ge,Ie,g,x,Se,r,st,Q.length,j,i,h]),y(()=>{(we||Ie)&&c.current&&c.current.pause()},[we,Ie,c]),y(()=>{const e=c.current;return()=>{it.current&&clearTimeout(it.current),e&&!e.ended&&Qe(e.currentTime,e.duration||0)}},[Qe,c]);const Cn=S(e=>{let n=null,s=!0;try{n=localStorage.getItem("tvLastSubtitle"),s=localStorage.getItem("tvSubtitlesEnabled")!=="false"}catch{}return Rn(e,{lastKey:n,enabled:s})},[]),kn=S(e=>{if(!(e<0))try{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e))}catch{}},[]),er=S(e=>{if(e.length===0)return 0;let n=null;try{n=localStorage.getItem("tvLastAudio")}catch{}if(n){const s=e.findIndex(H=>Mn(H)===n);if(s>=0)return s;const l=n.indexOf("|||"),u=l>=0?n.slice(0,l):n,N=l>=0?n.slice(l+3):n,d=e.findIndex(H=>H.language===u||H.label===N);if(d>=0)return d}return Rn(e,{lastKey:null,enabled:!0})},[]),{data:tr}=Fs(j||void 0),nr=xe(()=>(tr?.progress??[]).filter(n=>n.season===i&&(n.completed===!0||n.completed===1||An(n.currentTime,n.duration))).map(n=>String(n.episode)),[tr,i]),rr=xe(()=>Q.map(e=>({id:String(e.episode_number),label:`Episode ${e.episode_number}`,sublabel:e.name||void 0,thumbnail:e.still_path?`https://image.tmdb.org/t/p/w185${e.still_path}`:void 0})),[Q]),sr=xe(()=>(r?.genres??[]).map(e=>e.name).slice(0,5),[r]),En=xe(()=>[r?.year,r?.status,r?.number_of_seasons?`${r.number_of_seasons} Season${r.number_of_seasons>1?"s":""}`:null,r?.number_of_episodes?`${r.number_of_episodes} Episodes`:null].filter(Boolean),[r]);y(()=>{if(q.length!==0&&!q.some(e=>e.id===m)){const e=q.find(n=>n.tier==="direct")?.id??q[0].id;We(e);try{localStorage.setItem("tvProvider",e)}catch{}}},[q,m]),y(()=>{xt([]),Ut(""),Nt(!1)},[m]),y(()=>{if(le.length!==0&&!le.includes(ve)){Et(le[0]);try{localStorage.setItem("tvServer",le[0])}catch{}}},[le,ve]),y(()=>{if(!o){B(null),X([]),$e(""),A(""),ue("");return}const e=Number(o),n=R||"tv";B(null),X([]),$e(""),A(""),ue("");const s=parseInt(W.current.get("s")||"",10),l=parseInt(W.current.get("e")||"",10);ee(isNaN(s)?1:s),K(isNaN(l)?1:l),Fe(0),Ct.tv.details.query({type:n,id:String(e)}).then(u=>{const N={id:u.id,title:u.title||"",overview:u.overview||"",vote_average:u.vote_average,year:u.year,poster:u.poster,backdrop:u.backdrop,imdb_id:u.imdb_id||void 0,adult:u.adult,seasons:u.seasons,number_of_seasons:u.number_of_seasons};B(N),N.seasons&&N.seasons.length>0&&isNaN(s)&&ee(N.seasons[0].season_number)}).catch(()=>{})},[o,R]),y(()=>{if(!r||!o)return;if(!(r.seasons!==void 0||r.number_of_seasons!==void 0)){$([]);return}const n=parseInt(p.get("e")||"",10);Ct.tv.episodes.query({id:String(o),season:String(i)}).then(s=>{const l=(s.episodes||[]).map(u=>({episode_number:u.episode_number,name:u.name||"",vote_average:u.vote_average,overview:u.overview||"",still_path:u.still_path||""}));$(l),l.length!==0&&K(u=>!isNaN(n)&&l.some(N=>N.episode_number===n)?n:l.some(N=>N.episode_number===u)?u:l[0].episode_number)}).catch(()=>{})},[r,o,i,p]),y(()=>{if(!M||!r||!o)return;fetch(`/api/tv/embed/${m}/${g?"movie":"tv"}/${o}?season=${i}&episode=${h}`).then(n=>n.json()).then(n=>{if(n.url)return ue(n.url),fetch(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(s=>s.json()).then(s=>{s.finalUrl&&ue(s.finalUrl)})}).catch(()=>{})},[m,r,o,i,h,g,M]);const tn=S(async()=>{if(!r||!o||!m||M||r.adult&&!Mt)return;const e=`${j}:${i}:${h}`;Y(!0),A(""),ne.current.length===0&&(X([]),Fe(0),Ke([]),dt([]));try{const n=await G.fetchQuery({queryKey:Jt(i,h),queryFn:()=>en(i,h),staleTime:3e5,gcTime:18e5});if(Rt.current!==e){Y(!1);return}if(Y(!1),!n.valid||!n.sources?.length){A(n.error?`${n.error}`:le.length>0?`No streams from ${ve}. Try another server.`:"No streams available.");return}X(n.sources),$e(e),n.servers?.length&&xt(n.servers),n.embedUrl&&Ut(n.embedUrl),Fe(0),n.referer&&jt(n.referer);const s=n.audioTracks||[];Ke(s),C(s.length>0?er(s):0);const l=n.subtitles||[];if(dt(l),l.length>0){const d=Cn(l);Oe(d),kn(d)}else Oe(-1);const u=g?"movie":"tv",N=o;Ct.tv.subtitles.query({type:u,tmdbId:String(N),season:String(i),episode:String(h)}).then(d=>{if(Rt.current!==e)return;const H=Array.isArray(d.subtitles)?d.subtitles:[];H.length!==0&&dt(oe=>{const k=[...oe,...H.filter(J=>!oe.some(ge=>ge.url===J.url))];if(oe.length===0){const J=Cn(k);Oe(J),kn(J)}return k})}).catch(()=>{}),A("")}catch{if(Rt.current!==e)return;Y(!1),A("Failed to load streams.")}},[r,o,m,i,h,g,M,Mt,le,ve,Cn,kn,er,j,G,Jt,en]),Or=S(e=>{if(e==="Embed"){Nt(!0);return}Nt(!1),Et(e);try{localStorage.setItem("tvServer",e)}catch{}A("")},[]),Fr=S(e=>{We(e);try{localStorage.setItem("tvProvider",e)}catch{}},[]);y(()=>{m&&r&&!M&&tn()},[m,r,tn,M]),y(()=>{if(!c.current)return;if(ce.current&&(ce.current.destroy(),ce.current=null),M||b){const d=c.current;d&&(d.pause(),d.removeAttribute("src"),d.load());return}let e=!1;if(Ee){const d=c.current;return d&&(d.pause(),d.removeAttribute("src"),d.load(),d.src="/av-sync-test.mp4",yt.current||d.play().catch(()=>{})),()=>{e=!0}}if(Rt.current===`${j}:${i}:${h}`&&se.current==null&&!yt.current)try{const d=c.current;d&&!d.ended&&d.currentTime>1&&(se.current=d.currentTime)}catch{}const s=!Ce&&Re===`${j}:${i}:${h}`?b?"":D[Ne]?.url||"":"";if(!s){try{c.current?.pause(),c.current?.removeAttribute("src"),c.current?.load()}catch{}return}const l=c.current;l.pause(),l.removeAttribute("src"),l.load(),v.actions.resetMediaState();const u=`/api/tv/stream-proxy?url=${encodeURIComponent(s)}&referer=${encodeURIComponent(ut)}`;D[Ne]?.type==="hls"?(async()=>{const d=await Vs();if(!e)if(d&&d.isSupported()){const H=$o()||document.body.classList.contains("low-end"),oe=H?60:180,k=new d({enableWorker:!0,lowLatencyMode:!1,maxBufferLength:oe,maxMaxBufferLength:oe+(H?30:60),backBufferLength:H?30:60,maxBufferSize:(H?120:360)*1e3*1e3,fragLoadPolicy:{default:{maxTimeToFirstByteMs:15e3,maxLoadTimeMs:45e3,timeoutRetry:{maxNumRetry:2,retryDelayMs:0,maxRetryDelayMs:0},errorRetry:{maxNumRetry:3,retryDelayMs:800,maxRetryDelayMs:6e3}}},manifestLoadPolicy:{default:{maxTimeToFirstByteMs:1e4,maxLoadTimeMs:25e3,timeoutRetry:{maxNumRetry:1,retryDelayMs:500,maxRetryDelayMs:2e3},errorRetry:{maxNumRetry:2,retryDelayMs:800,maxRetryDelayMs:4e3}}}});ce.current=k,k.on(d.Events.ERROR,(I,E)=>{E.fatal&&(A(`Stream failed (${E.details}). Try another source or reload.`),Y(!1),k.destroy(),ce.current=null)}),k.loadSource(u),k.attachMedia(l);const J=()=>{let I=!1,E=0;try{I=localStorage.getItem("tvSubtitlesEnabled")==="true";const P=parseInt(localStorage.getItem("tvSelectedSubtitle")||"0",10);!isNaN(P)&&P>=0&&(E=P)}catch{}return{enabled:I,index:E}},ge=()=>{if(typeof k.subtitleTrack!="number")return;if(re.current.length>0){k.subtitleTrack=-1;return}const I=Array.isArray(k.subtitleTracks)?k.subtitleTracks:[];if(I.length===0){k.subtitleTrack=-1;return}const E=J();if(E.enabled){const P=E.index<I.length?E.index:0;k.subtitleTrack=P,Oe(P),fn()}else k.subtitleTrack=-1};Po(k,d.Events,{getWant:()=>It.current,onResolve:I=>C(I)}),k.on(d.Events.MANIFEST_PARSED,()=>{ge(),me.current!=null&&(l.currentTime=me.current,me.current=null),St(),!yt.current&&_t.current&&l.play().catch(()=>{})}),k.on(d.Events.SUBTITLE_TRACKS_UPDATED,()=>{ge()}),k.on(d.Events.SUBTITLE_TRACK_SWITCH,(I,E)=>{if(re.current.length>0){if(E.id!==-1)try{k.subtitleTrack=-1}catch{}return}const P=Array.isArray(k.subtitleTracks)?k.subtitleTracks:[];if(P.length!==0){if(E.id===-1){const O=J();if(O.enabled){const je=O.index<P.length?O.index:0;k.subtitleTrack=je;return}}Oe(E.id),fn()}})}else js(l)&&(l.src=u,me.current!=null&&(l.currentTime=me.current,me.current=null),St(),!yt.current&&_t.current&&l.play().catch(()=>{A("Failed to play stream. Try another source.")}))})():(l.src=u,me.current!=null&&(l.currentTime=me.current,me.current=null),St(),!yt.current&&_t.current&&l.play().catch(()=>{A("Failed to play stream. Try another source.")}));const N=()=>{const oe=l.error?.code===4?"Video source not supported or not found":"Failed to load video stream";A(`${oe}. The source may be invalid or expired. Try switching source or reloading.`),Y(!1)};return l.addEventListener("error",N),()=>{e=!0,l.removeEventListener("error",N)}},[D,Re,Ce,Ne,m,ut,M,b,c,me,Ee,j,i,h,St,fn,v.actions]),y(()=>{if(!ot||we||Ie||Ge||$t||M||Ee)return;const e=c.current;!e||!e.paused||e.ended||e.readyState<1||(St(),e.play().catch(()=>{}))},[ot,we,Ie,Ge,$t,M,Ee,St,c]),y(()=>{const e=ce.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=be)},[be]),y(()=>{const e=ce.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||re.current.length>0||(ie>=0?e.subtitleTrack=ie:e.subtitleTrack=-1)},[ie]),y(()=>{const e=c.current;if(!(!e||M)&&(e.querySelectorAll("track").forEach(n=>n.remove()),re.current=[],z.length!==0&&(z.forEach(n=>{const s=document.createElement("track");s.kind="subtitles",s.label=n.label||n.language||"Unknown",s.srclang=n.language||n.label||"en";const l=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(ut)}`;s.src=l,s.addEventListener("load",()=>{const u=re.current.indexOf(s),N=s.track;if(N&&u>=0){const d=u===ft.current;N.mode=d&&!gn.current?"showing":"hidden"}}),e.appendChild(s),re.current.push(s)}),z.length>0)))try{const n=ce.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[z,ut,M,m,c]),y(()=>{const e=c.current;if(!e||M)return;const n=ce.current;re.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const s=()=>{const N=$n(v.state.subtitleFontSize,e.clientHeight||720),d=Math.max(0,Math.min(100,100-v.state.subtitlePosition)),H=()=>{const I=N*16,E=e.videoHeight||e.clientHeight||720,P=e.videoWidth||e.clientWidth||1280;return{step:I*1.3/E*100,chars:Math.max(20,Math.floor(P/(I*.55)))}},oe=(I,E)=>{const P=I;P.snapToLines=!1,P.line=E},k=I=>{if(!I.cues)return;Array.from(I.cues).forEach(fe=>oe(fe,d));const E=Array.from(I.activeCues??[]);if(E.length<=1){E.forEach(fe=>oe(fe,d));return}const{step:P,chars:O}=H();let je=d;for(let fe=E.length-1;fe>=0;fe--){const Xe=String(E[fe].text??"").replace(/<[^>]*>/g,"").split(`
3
- `).reduce((sn,Ft)=>sn+Math.max(1,Math.ceil(Ft.length/O)),0);je=Math.max(0,je-Xe*P),oe(E[fe],je),je-=P*.4}},J=re.current;if(J.length>0){J.forEach((I,E)=>{const P=I.track;if(!P)return;const O=E===ie;P.mode=O&&!_e?"showing":"hidden",O&&!_e&&k(P)});return}const ge=Array.from(e.textTracks);ge.length!==0&&ge.forEach((I,E)=>{const P=E===ie;I.mode=P&&!_e?"showing":"hidden",P&&!_e&&k(I)})};s();const l=()=>s();e.textTracks.addEventListener("addtrack",l),e.addEventListener("loadedmetadata",s,{once:!0});const u=window.setTimeout(s,600);return()=>{e.textTracks.removeEventListener("addtrack",l),e.removeEventListener("loadedmetadata",s),window.clearTimeout(u)}},[ie,z,M,m,c,_e,v.state.subtitleFontSize,v.state.subtitlePosition]),y(()=>{if(!_e)return;const e=c.current,n=Bt.current;if(!e||!n)return;const s=Ye/1e3,l=At/1e3,u=new Set;let N=[],d=-1,H=-1,oe=-1,k=-1,J=0,ge=0,I=!1;const E=()=>{const U=ft.current;if(U<0)return null;const Ze=re.current;return Ze.length>0?Ze[U]?.track??null:Array.from(e.textTracks)[U]??null},P=(U,Ze)=>{const pe=U.cues;if(!pe||pe.length===0)return Array.from(U.activeCues??[]);let lt=0,ct=pe.length;for(;lt<ct;){const Le=lt+ct>>>1;pe[Le].endTime+s<Ze?lt=Le+1:ct=Le}const Vt=[];for(let Le=lt;Le<pe.length;Le++){const on=pe[Le];if(on.startTime+s>Ze)break;on.endTime+s>=Ze&&Vt.push(on)}return Vt},O=()=>{const U=E(),Ze=e.currentTime-l,pe=U?P(U,Ze):[],lt=e.clientWidth,ct=e.clientHeight,Vt=e.videoWidth,Le=e.videoHeight;if(pe.length===N.length&&pe.every((Nn,In)=>Nn===N[In])&&lt===d&&ct===H&&Vt===oe&&Le===k||(N=pe,d=lt,H=ct,oe=Vt,k=Le,n.textContent="",pe.length===0))return;const ir={fontSize:$n(v.state.subtitleFontSize,ct),position:v.state.subtitlePosition,bgOpacity:v.state.subtitleBgOpacity,bgColor:v.state.subtitleBgColor,textColor:v.state.subtitleTextColor,edge:v.state.subtitleEdge,bold:v.state.subtitleBold},Wr=bs(ir),zr=vs(e,ir.position);pe.forEach((Nn,In)=>{const lr=String(Nn.text??"");if(!ys(lr).trim())return;const Bn=document.createElement("div"),Hr=(pe.length-1-In)*1.7;Bn.style.cssText=`${Wr}
4
- bottom: calc(${zr}px + ${Hr}em);`,Bn.innerHTML=_s(lr),n.appendChild(Bn)})},je=()=>{Array.from(e.textTracks).forEach(U=>{u.has(U)||(u.add(U),U.addEventListener("cuechange",O))})},fe=()=>{je(),O()},xn=()=>{if(I||ge)return;const U=()=>{ge=0,!(I||e.paused||e.ended)&&(O(),xn())};ge=window.requestAnimationFrame(U)},Xe=e,sn=()=>{J=0,O(),!I&&Xe.requestVideoFrameCallback&&(J=Xe.requestVideoFrameCallback(sn))},Ft=()=>{O(),Xe.requestVideoFrameCallback?J||(J=Xe.requestVideoFrameCallback(sn)):xn()};je(),e.textTracks.addEventListener("addtrack",fe),e.textTracks.addEventListener("removetrack",fe),e.addEventListener("timeupdate",O),e.addEventListener("seeked",O),e.addEventListener("loadedmetadata",O),e.addEventListener("play",Ft);const or=Array.from(e.querySelectorAll("track"));or.forEach(U=>U.addEventListener("load",O));const ar=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>O());return ar?.observe(e),O(),Ft(),()=>{I=!0,u.forEach(U=>U.removeEventListener("cuechange",O)),e.textTracks.removeEventListener("addtrack",fe),e.textTracks.removeEventListener("removetrack",fe),e.removeEventListener("timeupdate",O),e.removeEventListener("seeked",O),e.removeEventListener("loadedmetadata",O),e.removeEventListener("play",Ft),or.forEach(U=>U.removeEventListener("load",O)),ar?.disconnect(),ge&&window.cancelAnimationFrame(ge),J&&Xe.cancelVideoFrameCallback&&Xe.cancelVideoFrameCallback(J),n.textContent=""}},[_e,Ye,ie,z,At,c,v.state.subtitleFontSize,v.state.subtitlePosition,v.state.subtitleBgOpacity,v.state.subtitleBgColor,v.state.subtitleTextColor,v.state.subtitleEdge,v.state.subtitleBold]);const nn=()=>{B(null),X([]),ue(""),F(-1)},Vr=S(e=>{ee(e),K(1),Me(e,1)},[Me]),rn=!g&&r?.seasons&&r.seasons.length>1?t("label",{className:f.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{value:i,onChange:e=>Vr(parseInt(e.target.value,10)||1),className:f.select,children:r.seasons.map(e=>t("option",{value:e.season_number,children:["Season ",e.season_number," (",e.episode_count," ep)"]},e.season_number))})]}):null,Tt=S(e=>{const n=parseInt(e,10);if(!isNaN(n)){try{c.current?.pause()}catch{}K(n),Me(i,n)}_n(!1)},[i,Me,c]);y(()=>{if(g)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(x!=null?Tt(String(x)):Zr.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[g,x,Tt]);const jr=e=>{C(e);try{const s=De[e];s&&localStorage.setItem("tvLastAudio",Mn(s))}catch{}const n=ce.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},Ur=e=>{Oe(e);try{if(e===-1)localStorage.setItem("tvSubtitlesEnabled","false");else{localStorage.setItem("tvSubtitlesEnabled","true"),localStorage.setItem("tvSelectedSubtitle",String(e));const u=z[e];u&&localStorage.setItem("tvLastSubtitle",Mn(u))}}catch{}const n=c.current,s=ce.current;if(s&&typeof s.subtitleTrack=="number"&&Array.isArray(s.subtitleTracks)&&s.subtitleTracks.length>0&&(s.subtitleTrack=re.current.length>0||e<0?-1:e),!n)return;const l=re.current;if(l.length>0){l.forEach((u,N)=>{const d=u.track;if(!d)return;const H=N===e;d.mode=H&&!_e?"showing":"hidden"});return}Array.from(n.textTracks).forEach((u,N)=>{const d=N===e;u.mode=d&&!_e?"showing":"hidden"})},Ot=S(()=>{if(!r)return;const e=c.current,n=g?"":`S${String(i).padStart(2,"0")}E${String(h).padStart(2,"0")}`;Ct.discord.tvPresence.mutate({title:r.title,episodeLabel:n,isPlaying:e?!e.paused&&!e.ended:!0,thumbnail:r.poster,currentTime:e?e.currentTime:0,duration:e&&e.duration||0,isAdult:r.adult===!0,sessionId:Lt.current}).catch(()=>{}),Ct.discord.heartbeat.mutate({sessionId:Lt.current}).catch(()=>{})},[r,g,i,h,c]);return y(()=>{if(!r)return;Ot();const e=window.setInterval(()=>{const n=c.current;(!n||!n.paused)&&Ot()},15e3);return()=>window.clearInterval(e)},[Ot,r,c]),y(()=>{if(!r||M||Ce||ke||D.length===0)return;const e=c.current;if(!e)return;const n=()=>Ot();return e.addEventListener("play",n),e.addEventListener("pause",n),e.addEventListener("seeked",n),()=>{e.removeEventListener("play",n),e.removeEventListener("pause",n),e.removeEventListener("seeked",n)}},[r,M,Ce,ke,D,Ot,c]),y(()=>{const e=Lt.current,n=()=>Jr(e),s=()=>n();return window.addEventListener("pagehide",s),window.addEventListener("beforeunload",s),()=>{window.removeEventListener("pagehide",s),window.removeEventListener("beforeunload",s),n()}},[]),y(()=>{if(!r){document.title="TV & Movies - dango";return}document.title=g?`${r.title} - dango`:`${r.title} - Season ${i} Episode ${h} - dango`},[r,g,i,h]),y(()=>{if(!r||g)return;const e=new URLSearchParams(p),n=e.get("s"),s=e.get("e"),l=String(i),u=String(h);n===l&&s===u||(e.set("type",p.get("type")||"tv"),e.set("s",l),e.set("e",u),F(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[r,g,i,h,p,F]),t("div",{className:`${Je.playerPageLayout} ${Ae?Je.theaterMode:""}`,onClick:kr,children:[Ae&&t(Ss,{videoRef:c,active:hn.enabled&&!M&&D.length>0&&!ke&&!(r?.adult&&!Mt),settings:hn}),!Ae&&t("aside",{className:Je.episodeSidebar,children:r?g?t("div",{className:f.sidebarPosterCard,children:[r.poster&&t("img",{src:`https://image.tmdb.org/t/p/w342${r.poster}`,alt:r.title,loading:"lazy",decoding:"async"}),t("div",{className:f.sidebarPosterMeta,children:[t("strong",{children:r.title}),t("span",{children:r.year})]})]}):t(Ts,{episodes:rr,currentEpisode:String(h),watchedEpisodes:nr,onEpisodeClick:Tt,header:rn}):g?t("div",{className:f.statusMsg,children:[t(V,{name:"spinner",className:f.spinner})," Loading..."]}):t(Cs,{variant:"sidebar"})}),t("div",{className:Je.playerMain,children:[r&&t("div",{className:f.playerSection,onContextMenu:e=>e.preventDefault(),style:r.adult&&!Mt?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:M&&kt?t("iframe",{src:kt,className:f.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!M&&tt?t("iframe",{src:tt,className:f.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!M&&(D.length>0||Ce)?t(Pe,{children:[ke&&t(ur,{error:ke,onRetry:tn}),t(Ao,{player:v,title:r.title,episodeLabel:g?void 0:`S${i} E${h}`,audioTracks:De,selectedAudioTrack:be,onAudioTrackChange:jr,subtitles:z,selectedSubtitle:ie,onSubtitleChange:Ur,streams:D,resolutionIdx:Ne,onResolutionChange:Fe,onBack:nn,videoDelayEnabled:pt,onVideoDelayToggle:L,videoDelayMs:wt,onVideoDelayChange:Z,onCalibrateAvSync:Ht,subtitleDelayMs:Ye,onSubtitleDelayChange:gr,showNextEpisodeButton:_r&&!we&&!Ie&&!Ge,onNextEpisode:Zn,isLoading:Ce,isTheaterMode:Ae,onTheaterModeToggle:Sn,ambientSettings:hn,onAmbientChange:fr,children:[t("video",{ref:c,autoPlay:ot&&!$t,playsInline:!0,disablePictureInPicture:!0,className:`${f.video} ${mn?f.videoHidden:""}`,onTimeUpdate:Br,onEnded:()=>{Ee||wr()},onPlay:Ar,onPause:Mr,onSeeked:()=>{Gn.current=Date.now(),Dt()},onLoadedMetadata:Lr,onVolumeChange:v.actions.onVolumeChange,onWaiting:v.actions.onWaiting,onPlaying:v.actions.onPlaying,onCanPlay:v.actions.onCanPlay,onContextMenu:e=>e.preventDefault(),onError:()=>{A("Video failed to load. Try another server or reload."),Y(!1)}}),t("canvas",{ref:nt,className:`${f.delayCanvas} ${mn?f.delayCanvasActive:""}`}),_e&&t("div",{ref:Bt,className:f.subtitleOverlay}),t(ks,{isOpen:de,ms:wt,onChange:Z,onApply:Dn,onClose:qe,testClipActive:Ee,onTestClip:dn})]})]}):ke&&!M?t(ur,{error:ke,onRetry:tn}):null}),!Ae&&r&&t(Es,{}),!Ae&&rn&&t("div",{className:f.mobileSeasonRow,children:rn}),!Ae&&r&&t("div",{className:f.providerSelectWrap,children:t("label",{className:f.controlLabel,children:["Source",t("select",{value:m,onChange:e=>Fr(e.target.value),className:f.select,disabled:q.length===0,children:et?t("option",{value:"",children:"Loading..."}):q.length===0?t("option",{value:"",children:"No providers available"}):t(Pe,{children:[T.length>0&&t("optgroup",{label:"Direct HLS",children:T.map(e=>t("option",{value:e.id,children:e.label},e.id))}),te.length>0&&t("optgroup",{label:"Embeds",children:te.map(e=>t("option",{value:e.id,children:e.label},e.id))})]})})]})}),!Ae&&r&&!M&&(Ce?t("div",{className:f.sourceLoader,children:t("div",{className:f.ringSpinner})}):t(Lo,{servers:ye,selectedServer:Wt?"Embed":ve,onServerSelect:Or})),!Ae&&r&&t("div",{className:Je.playerInfoContainer,children:[t("div",{className:Je.playerInfoHeader,children:[t("div",{className:Je.playerAnimeCard,children:r.poster&&t("img",{src:`https://image.tmdb.org/t/p/w342${r.poster}`,alt:r.title,loading:"lazy",decoding:"async"})}),t("div",{className:Je.videoTitleSection,children:[t("div",{className:Te.titleContainer,children:[t("h1",{children:r.title}),t("div",{className:f.meta,children:[t("span",{className:f.year,children:r.year}),r.vote_average!=null&&r.vote_average>0&&t("span",{className:f.rating,children:[t(V,{name:"star",size:12}),Number(r.vote_average).toFixed(1)]}),t("span",{className:`${f.typeBadge} ${f[g?"movie":"tv"]}`,children:g?"Movie":"TV Show"})]}),sr.length>0&&t("div",{className:f.genreRow,children:sr.map(e=>t("span",{className:f.genreChip,children:e},e))}),En.length>0&&t("div",{className:f.metaRow,children:En.map((e,n)=>t("span",{children:[e,n<En.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:Te.controls,children:[t("button",{className:`${Te.watchlistBtn} ${Yt?Te.inList:""}`,onClick:yr,disabled:vr,type:"button",children:[Yt?t(V,{name:"check",size:14}):t(V,{name:"plus",size:14}),Yt?"In Watchlist":"Add to Watchlist"]}),!g&&t(Pe,{children:[t("button",{className:`${Te.watchlistBtn}`,onClick:()=>pn!=null&&Tt(String(pn)),disabled:pn==null,type:"button",children:[t(V,{name:"chevron-left",size:14}),"Prev EP"]}),t("button",{className:`${Te.watchlistBtn}`,onClick:()=>x!=null&&Tt(String(x)),disabled:x==null,type:"button",children:["Next EP",t(V,{name:"chevron-right",size:14})]}),!g&&t("button",{className:`${Te.watchlistBtn} ${Te.modeToggleBtn} ${vt?Te.modeToggleActive:""}`,onClick:()=>Nr(!vt),type:"button","aria-pressed":vt,children:vt?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),Er&&t("button",{className:`${Te.watchlistBtn}`,onClick:()=>_n(!0),type:"button",children:[t(V,{name:"list-ul",size:14}),"Episodes"]})]})]})]})]}),t("div",{className:Te.descriptionSection,children:[t("h3",{children:"Synopsis"}),t(Ws,{text:r.overview,emptyText:"No description available."})]}),t("button",{className:Te.detailsToggleBtn,onClick:()=>Tr(!Zt),type:"button",children:[Zt?t(V,{name:"chevron-up"}):t(V,{name:"chevron-down"}),Zt?"Hide Details":"Show Details"]}),Zt&&t("div",{className:f.detailGrid,children:[r.first_air_date&&t("div",{className:f.detailItem,children:[t("strong",{children:g?"Release Date":"First Air Date"}),t("span",{children:r.first_air_date})]}),r.last_air_date&&t("div",{className:f.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:r.last_air_date})]}),r.networks&&r.networks.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Networks"}),t("span",{children:r.networks.map(e=>e.name).join(", ")})]}),r.created_by&&r.created_by.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Created By"}),t("span",{children:r.created_by.map(e=>e.name).join(", ")})]}),r.episode_run_time&&r.episode_run_time.length>0&&t("div",{className:f.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[r.episode_run_time[0]," min"]})]}),r.imdb_id&&t("div",{className:f.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${r.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:f.imdbLink,children:"View on IMDb"})]})]})]}),!g&&t(xs,{isOpen:Cr,onClose:()=>_n(!1),episodes:rr,currentEpisode:String(h),watchedEpisodes:nr,onEpisodeClick:Tt,header:rn}),r?.adult&&!Mt&&t(wn,{isOpen:!0,title:"Content Warning",onClose:nn,children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t("p",{children:"This title contains mature content intended for adult audiences."}),t("p",{children:["By proceeding, you confirm that you are ",t("strong",{children:"18 years of age or older"})," ","(or the age of majority in your jurisdiction) and wish to view this content."]}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center"},children:[t(Ue,{variant:"secondary",onClick:nn,children:"Go Back"}),t(Ue,{onClick:pr,children:"I'm 18+, Continue"})]})]})}),t(Ns,{isOpen:we,onClose:Xn,title:"Resume Watching",message:t(Pe,{children:["You were at ",t("strong",{children:cn(bt)})]}),restartLabel:"Start from Beginning",onResume:Pr,onRestart:Xn}),t(wn,{isOpen:Ie,onClose:Rr,title:g?"Movie Completed":"Episode Completed",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t("p",{children:g?t(Pe,{children:"You've already watched this movie."}):t(Pe,{children:["You've already watched"," ",t("strong",{children:["Season ",i," Episode ",h]}),". Would you like to continue?"]})}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(Ue,{variant:"secondary",onClick:$r,children:"Replay"}),x!=null?t(Ue,{onClick:Zn,children:["Watch EP ",x]}):Se!=null?t(Ue,{onClick:Jn,children:["Start Season ",Se]}):null]})]})}),t(wn,{isOpen:Ge,onClose:()=>at(!1),title:g?"Movie Completed!":Se!=null?"Season Complete!":"Show Completed!",children:t("div",{style:{padding:"1rem",textAlign:"center"},children:[t(V,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)",marginBottom:"0.5rem"}}),t("p",{style:{fontSize:"1.1rem",fontWeight:600},children:Sr}),t("p",{style:{color:"var(--text-secondary)"},children:g?"You finished this movie!":Se!=null?`You finished Season ${i}.`:"Congratulations! You finished all available episodes."}),t("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center",flexWrap:"wrap"},children:[t(Ue,{variant:"secondary",onClick:()=>at(!1),children:"Close"}),Se!=null?t(Ue,{onClick:Jn,children:["Start Season ",Se]}):t(Pe,{children:[t(Ue,{onClick:()=>{at(!1),nn()},children:"Back to Details"}),Yt&&t(Ue,{onClick:Dr,disabled:qt.isPending,children:qt.isPending?"Saving...":"Move to Completed"})]})]})]})}),!r&&t("div",{className:f.statusMsg,children:[t(V,{name:"spinner",className:f.spinner})," Loading..."]})]})]})};export{Za as default};