@serifpersia/dango 4.0.7 → 4.0.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 (113) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/AmbientLightMenu-CO10UIKM.js +1 -0
  3. package/client/dist/assets/{AnimeCard-CcvD-9Bi.js → AnimeCard-fC2KO9iC.js} +1 -1
  4. package/client/dist/assets/{AnimeInfo-t3qfap0B.js → AnimeInfo-KjBye_qd.js} +1 -1
  5. package/client/dist/assets/{AnimeInfoPage-D3vtcWL7.js → AnimeInfoPage-C73_sIog.js} +2 -2
  6. package/client/dist/assets/{Asmr-GHxClLoM.js → Asmr-Bl73R_56.js} +1 -1
  7. package/client/dist/assets/{AsmrPopup-Bt7wZkV8.js → AsmrPopup-BbvhL78t.js} +1 -1
  8. package/client/dist/assets/{AsmrResetProgressModal-Di6VgAZx.js → AsmrResetProgressModal-DuuqDv23.js} +1 -1
  9. package/client/dist/assets/Home-CoBFY-dI.css +1 -0
  10. package/client/dist/assets/Home-DtBGTNur.js +1 -0
  11. package/client/dist/assets/{Insights-B-jf5_UY.js → Insights-DRgipISO.js} +1 -1
  12. package/client/dist/assets/{LibraryListPage-B5q00Vno.js → LibraryListPage-DJcL0lfR.js} +1 -1
  13. package/client/dist/assets/{ListeningList-BNUrMPyA.js → ListeningList-KC8x2JTx.js} +1 -1
  14. package/client/dist/assets/{Manga-SYhXSYV_.js → Manga-DRLYjZ32.js} +1 -1
  15. package/client/dist/assets/{MangaInfoPage-CsGcpQ4g.js → MangaInfoPage-Dg5FyjKC.js} +1 -1
  16. package/client/dist/assets/{MangaReadPage-B0BKdQeU.js → MangaReadPage-CHMXWOeU.js} +1 -1
  17. package/client/dist/assets/{MangaResetProgressModal-8Q_Jp8Tk.js → MangaResetProgressModal-6C_7cQ9-.js} +1 -1
  18. package/client/dist/assets/Mature-DintSvcm.js +1 -0
  19. package/client/dist/assets/{MatureConsentModal-DoPl5ONK.js → MatureConsentModal-D2QxzAd5.js} +1 -1
  20. package/client/dist/assets/{MediaCard-Ce90T0yC.js → MediaCard-B13pU_sD.js} +1 -1
  21. package/client/dist/assets/{Player-CYrY9dNs.js → Player-D7JxeeEa.js} +6 -6
  22. package/client/dist/assets/{PlayerProvider-CjctET1A.js → PlayerProvider-BPOUTsvo.js} +1 -1
  23. package/client/dist/assets/PlayerSettings-Bn9-36NI.js +1 -0
  24. package/client/dist/assets/{PlayerSurface-B_rgFBYD.js → PlayerSurface-DRZlkk9L.js} +1 -1
  25. package/client/dist/assets/{QueueOptionsButton-BHkP1DB_.js → QueueOptionsButton-NMKIXk8k.js} +1 -1
  26. package/client/dist/assets/{QueueRail-CxtCW4xn.js → QueueRail-BMqj7tA1.js} +1 -1
  27. package/client/dist/assets/{ReadingList-C0hu5BhB.js → ReadingList-D3YqOY3n.js} +1 -1
  28. package/client/dist/assets/{ResetProgressModal-CncQLVw1.js → ResetProgressModal-Dw-OK0wI.js} +1 -1
  29. package/client/dist/assets/{Search-J3jIU8gd.js → Search-BWa4iAdv.js} +1 -1
  30. package/client/dist/assets/{Settings-B8jClutS.js → Settings-DGNoqBtn.js} +2 -2
  31. package/client/dist/assets/{SkeletonGrid-zCAxRZIz.js → SkeletonGrid-xGtg97zD.js} +1 -1
  32. package/client/dist/assets/{Trackers-DTlCK6Gw.js → Trackers-DpD8kLrJ.js} +1 -1
  33. package/client/dist/assets/Tv-gfhcHTMv.js +4 -0
  34. package/client/dist/assets/{TvInfo-Co-CnIbQ.js → TvInfo-h4NE1IP0.js} +1 -1
  35. package/client/dist/assets/TvPopup-on4rxc10.js +1 -0
  36. package/client/dist/assets/{TvSearch-dkkP831q.js → TvSearch-BoWPuHhz.js} +1 -1
  37. package/client/dist/assets/{TvWatchlist-CTxHqUB9.js → TvWatchlist-CZsKdghE.js} +1 -1
  38. package/client/dist/assets/{VirtualKeyboard-ClY9H0vl.js → VirtualKeyboard-BWvLAbre.js} +1 -1
  39. package/client/dist/assets/{WatchAlong-RAJe62YS.js → WatchAlong-BQ1knfz0.js} +1 -1
  40. package/client/dist/assets/{WatchAlongPanel-G2j2eopw.js → WatchAlongPanel-D_ToyGjh.js} +1 -1
  41. package/client/dist/assets/{Watchlist-D8prt4l1.js → Watchlist-4P7nHRSB.js} +1 -1
  42. package/client/dist/assets/atkinson-hyperlegible-latin-400-normal-BbWidj28.woff +0 -0
  43. package/client/dist/assets/atkinson-hyperlegible-latin-400-normal-BrHNak5F.woff2 +0 -0
  44. package/client/dist/assets/atkinson-hyperlegible-latin-700-normal-BK6Glc0m.woff +0 -0
  45. package/client/dist/assets/atkinson-hyperlegible-latin-700-normal-GZI4o3u0.woff2 +0 -0
  46. package/client/dist/assets/atkinson-hyperlegible-latin-ext-400-normal-Bbz-b3yf.woff +0 -0
  47. package/client/dist/assets/atkinson-hyperlegible-latin-ext-400-normal-DRk46D-x.woff2 +0 -0
  48. package/client/dist/assets/atkinson-hyperlegible-latin-ext-700-normal-BoVPHkS0.woff2 +0 -0
  49. package/client/dist/assets/atkinson-hyperlegible-latin-ext-700-normal-CKkU2Dpt.woff +0 -0
  50. package/client/dist/assets/bangers-latin-400-normal-BAEm-Pv0.woff +0 -0
  51. package/client/dist/assets/bangers-latin-400-normal-DeHY8Ncq.woff2 +0 -0
  52. package/client/dist/assets/bangers-latin-ext-400-normal-7BLmjjiv.woff2 +0 -0
  53. package/client/dist/assets/bangers-latin-ext-400-normal-CzVt_Cgx.woff +0 -0
  54. package/client/dist/assets/bangers-vietnamese-400-normal-BbvBhFjQ.woff2 +0 -0
  55. package/client/dist/assets/bangers-vietnamese-400-normal-Ll9rymNv.woff +0 -0
  56. package/client/dist/assets/bree-serif-latin-400-normal-DFKDEHQE.woff2 +0 -0
  57. package/client/dist/assets/bree-serif-latin-400-normal-Dbaz2OwO.woff +0 -0
  58. package/client/dist/assets/bree-serif-latin-ext-400-normal-CnorAOA2.woff +0 -0
  59. package/client/dist/assets/bree-serif-latin-ext-400-normal-amfO-E0k.woff2 +0 -0
  60. package/client/dist/assets/chakra-petch-latin-400-normal-D7EtbySE.woff +0 -0
  61. package/client/dist/assets/chakra-petch-latin-400-normal-SafcrIr2.woff2 +0 -0
  62. package/client/dist/assets/chakra-petch-latin-700-normal-CnDBPjkL.woff2 +0 -0
  63. package/client/dist/assets/chakra-petch-latin-700-normal-D1s_c2du.woff +0 -0
  64. package/client/dist/assets/chakra-petch-latin-ext-400-normal-C8u6EFkq.woff2 +0 -0
  65. package/client/dist/assets/chakra-petch-latin-ext-400-normal-MNNNbyh_.woff +0 -0
  66. package/client/dist/assets/chakra-petch-latin-ext-700-normal-BeviJPUl.woff +0 -0
  67. package/client/dist/assets/chakra-petch-latin-ext-700-normal-DAkvJhej.woff2 +0 -0
  68. package/client/dist/assets/chakra-petch-thai-400-normal-Bw1Q-fVY.woff2 +0 -0
  69. package/client/dist/assets/chakra-petch-thai-400-normal-KdzBjiWs.woff +0 -0
  70. package/client/dist/assets/chakra-petch-thai-700-normal-B7WL5pBr.woff2 +0 -0
  71. package/client/dist/assets/chakra-petch-thai-700-normal-vZLZ_5L8.woff +0 -0
  72. package/client/dist/assets/chakra-petch-vietnamese-400-normal-Cn7ya5On.woff +0 -0
  73. package/client/dist/assets/chakra-petch-vietnamese-700-normal-gQuUA8Wu.woff +0 -0
  74. package/client/dist/assets/comic-neue-latin-400-normal-BdhG8RSD.woff2 +0 -0
  75. package/client/dist/assets/comic-neue-latin-400-normal-CU7kPFAv.woff +0 -0
  76. package/client/dist/assets/comic-neue-latin-700-normal-NE4Vcoll.woff2 +0 -0
  77. package/client/dist/assets/comic-neue-latin-700-normal-yR9qu__P.woff +0 -0
  78. package/client/dist/assets/{index-BOJFs4B4.js → index-CqcwUuWG.js} +2 -2
  79. package/client/dist/assets/{libraryInvalidation-1xwHWgGv.js → libraryInvalidation-CC9NocI9.js} +1 -1
  80. package/client/dist/assets/oswald-cyrillic-ext-wght-normal-DLWmRmaW.woff2 +0 -0
  81. package/client/dist/assets/oswald-cyrillic-wght-normal-C8sJyxwB.woff2 +0 -0
  82. package/client/dist/assets/oswald-latin-ext-wght-normal-Dj_1K-Kw.woff2 +0 -0
  83. package/client/dist/assets/oswald-latin-wght-normal-CzS3kehr.woff2 +0 -0
  84. package/client/dist/assets/oswald-vietnamese-wght-normal-Tdf5mmdl.woff2 +0 -0
  85. package/client/dist/assets/{playbackCompletion-BpEGpC-Z.js → playbackCompletion-DasRrCt1.js} +1 -1
  86. package/client/dist/assets/russo-one-cyrillic-400-normal-BXZIn0h3.woff2 +0 -0
  87. package/client/dist/assets/russo-one-cyrillic-400-normal-rRbrNFRA.woff +0 -0
  88. package/client/dist/assets/russo-one-latin-400-normal-BfOuQF9V.woff2 +0 -0
  89. package/client/dist/assets/russo-one-latin-400-normal-CosRecV9.woff +0 -0
  90. package/client/dist/assets/russo-one-latin-ext-400-normal-BssN3Pxm.woff +0 -0
  91. package/client/dist/assets/russo-one-latin-ext-400-normal-CezFp_e4.woff2 +0 -0
  92. package/client/dist/assets/useAnimeInfoData-BlTijixl.js +1 -0
  93. package/client/dist/assets/{useMangaLibrary-OgS0RRdO.js → useMangaLibrary-BMioQUxH.js} +1 -1
  94. package/client/dist/assets/{useMangaPopup-Eyed-Gg3.js → useMangaPopup-Dzqm7EW7.js} +1 -1
  95. package/client/dist/assets/{useTv-SLXsIWFQ.js → useTv-iD-DnP_2.js} +1 -1
  96. package/client/dist/assets/{useTvLibrary-F0S6WnwD.js → useTvLibrary-D9vDuZs7.js} +1 -1
  97. package/client/dist/assets/useWatchAlongPlayer-BksJHCzs.css +1 -0
  98. package/client/dist/assets/useWatchAlongPlayer-DC5cqK1c.js +11 -0
  99. package/client/dist/index.html +1 -1
  100. package/client/dist/subtitle-font-licenses.txt +113 -0
  101. package/package.json +2 -2
  102. package/server/dist/server.js +1 -1
  103. package/server/package.json +1 -1
  104. package/client/dist/assets/Home-Bmc4hGfd.css +0 -1
  105. package/client/dist/assets/Home-C9caLBqU.js +0 -1
  106. package/client/dist/assets/Mature-DtyWIW42.js +0 -1
  107. package/client/dist/assets/OptionListMenu-CHqo2pTO.js +0 -1
  108. package/client/dist/assets/PlayerSettings-uDMPYAlP.js +0 -1
  109. package/client/dist/assets/Tv-CnahgiVt.js +0 -4
  110. package/client/dist/assets/TvPopup-Ci4SXMWf.js +0 -1
  111. package/client/dist/assets/useAnimeInfoData-CvV6vRjn.js +0 -1
  112. package/client/dist/assets/useWatchAlongPlayer-BsaopdPw.css +0 -1
  113. package/client/dist/assets/useWatchAlongPlayer-D-fPdbp2.js +0 -10
@@ -1,2 +1,2 @@
1
- import{h as J,d as i,A as ye,u as e,S as g,g as ea,q as De}from"./vendor-core-DfaOB3Rn.js";import{u as Z,b as R,a as S}from"./vendor-query-BBT5_sHx.js";import{L as r,q as s,t as c,an as aa,w as na,Z as qe,B as ge}from"./index-BOJFs4B4.js";import{I as m}from"./vendor-icons-C1Pj_eSX.js";function ta(){const N=Z();J(()=>{const C=new URLSearchParams(window.location.search),h=C.get("mal");if(!h)return;const t=C.get("user"),y=C.get("reason");window.history.replaceState(null,"",window.location.pathname),h==="success"?(r.success(t?`Connected to MyAnimeList as ${decodeURIComponent(t)}`:"Connected to MyAnimeList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(y?decodeURIComponent(y):"MyAnimeList authentication failed")},[N])}function sa(){const N=Z(),[C,h]=i(!1);return J(()=>{const t=new URLSearchParams(window.location.search),y=t.get("anilist");if(y){const k=t.get("user"),u=t.get("reason");window.history.replaceState(null,"",window.location.pathname),y==="success"?(r.success(k?`Connected to AniList as ${decodeURIComponent(k)}`:"Connected to AniList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(u?decodeURIComponent(u):"AniList authentication failed");return}const b=new URLSearchParams(window.location.hash.substring(1)),l=b.get("access_token"),L=t.get("code");if(!l&&!L){const k=b.get("error");k&&(r.error(`AniList error: ${k}`),window.history.replaceState(null,"",window.location.pathname));return}const d=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),h(!0),r("Connecting to AniList..."),c.tracker.anilistAuth.mutate(l?{token:l}:{code:L,redirectUri:d}).then(async k=>{const u=k.user;r.success(`Connected to AniList as ${u?.name??"AniList user"}`),N.invalidateQueries({queryKey:[s.trackerStatus]})}).catch(k=>{r.error(k instanceof Error?k.message:"Failed to authenticate with AniList")}).finally(()=>{h(!1)})},[N]),C}const ia="_header_azjok_1",ra="_fadeIn_azjok_1",ca="_pageTitle_azjok_6",oa="_pageSubtitle_azjok_14",la="_importCard_azjok_20",da="_cardHeader_azjok_31",ma="_uploadArea_azjok_49",ua="_fileInputWrapper_azjok_53",pa="_fileInput_azjok_53",ha="_fileDisplay_azjok_71",ga="_fileIcon_azjok_79",ya="_fileName_azjok_84",ka="_browseButton_azjok_93",fa="_optionsArea_azjok_104",_a="_checkboxLabel_azjok_112",ba="_checkbox_azjok_112",va="_checkboxCustom_azjok_125",Na="_optionText_azjok_153",wa="_optionTitle_azjok_159",Ca="_optionDesc_azjok_165",Ia="_actions_azjok_171",Sa="_importBtn_azjok_179",La="_cancelBtn_azjok_185",Ma="_statusMessage_azjok_199",xa="_success_azjok_209",Ta="_error_azjok_215",Aa="_progressSection_azjok_221",za="_progressBar_azjok_226",Pa="_progressFill_azjok_234",ja="_progressInfo_azjok_241",Ba="_progressCount_azjok_248",Ea="_progressTitle_azjok_255",Fa="_sourceBadge_azjok_273",Da="_anilist_azjok_285",qa="_kitsu_azjok_291",$a="_offline_azjok_297",Ka="_skipped_azjok_303",Ra="_cardTitleRow_azjok_308",Ua="_anilistIcon_azjok_318",Qa="_malIcon_azjok_324",Oa="_badgeOnline_azjok_330",Ha="_badgeOffline_azjok_342",Ga="_connectedProfile_azjok_354",Wa="_avatar_azjok_361",Xa="_connectedInfo_azjok_368",Ya="_connectedName_azjok_376",Ja="_connectedHint_azjok_382",Za="_loginPrompt_azjok_387",Va="_loginSection_azjok_395",en="_primaryBtn_azjok_401",an="_fieldLabel_azjok_405",nn="_helpText_azjok_424",tn="_resetBtn_azjok_431",sn="_loginText_azjok_461",rn="_secondaryBtn_azjok_471",cn="_syncBtn_azjok_472",on="_divider_azjok_525",ln="_actionSection_azjok_531",dn="_inputGroup_azjok_545",mn="_credentialFields_azjok_551",un="_credentialField_azjok_551",pn="_input_azjok_545",hn="_syncSummary_azjok_587",gn="_syncErrors_azjok_593",yn="_spin_azjok_597",kn="_radioGroup_azjok_616",fn="_radioLabel_azjok_623",_n="_syncHint_azjok_661",bn="_importLoading_azjok_668",a={header:ia,fadeIn:ra,pageTitle:ca,pageSubtitle:oa,importCard:la,cardHeader:da,uploadArea:ma,fileInputWrapper:ua,fileInput:pa,fileDisplay:ha,fileIcon:ga,fileName:ya,browseButton:ka,optionsArea:fa,checkboxLabel:_a,checkbox:ba,checkboxCustom:va,optionText:Na,optionTitle:wa,optionDesc:Ca,actions:Ia,importBtn:Sa,cancelBtn:La,statusMessage:Ma,success:xa,error:Ta,progressSection:Aa,progressBar:za,progressFill:Pa,progressInfo:ja,progressCount:Ba,progressTitle:Ea,sourceBadge:Fa,anilist:Da,kitsu:qa,offline:$a,skipped:Ka,cardTitleRow:Ra,anilistIcon:Ua,malIcon:Qa,badgeOnline:Oa,badgeOffline:Ha,connectedProfile:Ga,avatar:Wa,connectedInfo:Xa,connectedName:Ya,connectedHint:Ja,loginPrompt:Za,loginSection:Va,primaryBtn:en,fieldLabel:an,helpText:nn,resetBtn:tn,loginText:sn,secondaryBtn:rn,syncBtn:cn,divider:on,actionSection:ln,inputGroup:dn,credentialFields:mn,credentialField:un,input:pn,syncSummary:hn,syncErrors:gn,spin:yn,radioGroup:kn,radioLabel:fn,syncHint:_n,importLoading:bn},ie="tracker_anilist_client_id",Re="49887".trim(),re=!!Re;function $e(){const N=Z(),[C,h]=i(""),t=ye(!1),y=sa(),{data:b}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query()}),{data:l}=R({queryKey:[s.anilistClientId],queryFn:async()=>(await c.settings.getByKey.query({key:ie})).value||""});J(()=>{t.current||l===void 0||(l&&h(l),t.current=!0)},[l]);const L=S({mutationFn:()=>c.tracker.anilistDisconnect.mutate(),onSuccess:()=>{N.invalidateQueries({queryKey:[s.trackerStatus]}),r.success("Disconnected from AniList")},onError:_=>r.error(_.message)}),d=S({mutationFn:()=>c.settings.set.mutate({key:ie,value:""}),onSuccess:()=>{h(""),N.invalidateQueries({queryKey:[s.anilistClientId]}),r.success("Switched to dango's AniList app")},onError:_=>r.error(_.message)}),k=async()=>{const _=C.trim(),o=_||Re;if(!o){r.error("Enter your AniList client ID first");return}const P=(l||"").trim();try{_?_!==l&&await c.settings.set.mutate({key:ie,value:_}):re&&P&&await c.settings.set.mutate({key:ie,value:""}),N.invalidateQueries({queryKey:[s.anilistClientId]})}catch(M){r.error(M.message);return}const p=encodeURIComponent(window.location.origin+window.location.pathname);window.location.href=`https://anilist.co/api/v2/oauth/authorize?client_id=${encodeURIComponent(o)}&response_type=token&state=${p}`},u=b?.anilist?.user??null;return b?.anilist?.connected&&u?e("div",{className:a.connectedProfile,children:[u.avatar&&e("img",{src:u.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:u.name}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>L.mutate(),disabled:L.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:["Log in with AniList to enable bidirectional progress & status synchronization.",y&&e("span",{style:{marginLeft:8,color:"var(--accent)"},children:"Finishing login…"})]}),e("div",{className:a.fieldLabel,children:["AniList client ID - defaults to dango's app"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]})]}),e("div",{className:a.inputGroup,children:[e("input",{type:"text",placeholder:"Client ID",value:C,onChange:_=>h(_.currentTarget.value),className:a.input}),e("button",{className:a.primaryBtn,onClick:k,disabled:!(C.trim()||re),children:[e(m,{name:"external-link-alt"})," Connect"]})]}),re&&l&&e("button",{className:a.resetBtn,onClick:()=>d.mutate(),disabled:d.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:re?e(g,{children:["By default uses dango's client. To use your own AniList app: create it at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste only the ",e("strong",{children:"Client ID"})," above (leave empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste the"," ",e("strong",{children:"Client ID"})," above."]})})]})}function Ke({kind:N="anime",active:C=!0}){const h=Z(),[t,y]=i(""),[b,l]=i(""),[L,d]=i(""),[k,u]=i(""),_=ye(!1),{data:o}=R({queryKey:[s.malClientConfig],queryFn:()=>c.tracker.malConfig.query()}),{data:P}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query(),refetchInterval:15e3});J(()=>{o&&!_.current&&(y(o.clientId),_.current=!0)},[o]);const p=S({mutationFn:async()=>{d(""),(b.trim()||t.trim()&&t.trim()!==o?.clientId)&&await c.tracker.malSaveConfig.mutate({clientId:t.trim(),clientSecret:b.trim()||void 0}),l("");const f=await c.tracker.malLogin.mutate({redirectUri:`${window.location.origin}/api/tracker/mal/callback`});window.location.assign(f.url)},onError:f=>d(f.message)}),M=S({mutationFn:()=>c.tracker.malDisconnect.mutate(),onSuccess:()=>{h.invalidateQueries({queryKey:[s.trackerStatus]}),u(""),d(""),r.success("Disconnected from MyAnimeList")},onError:f=>d(f.message)}),B=S({mutationFn:()=>c.tracker.malClearConfig.mutate(),onSuccess:()=>{y(""),l(""),u(""),d(""),h.invalidateQueries({queryKey:[s.trackerStatus]}),h.invalidateQueries({queryKey:[s.malClientConfig]}),r.success("Switched to dango's MyAnimeList app - reconnect to finish")},onError:f=>d(f.message)}),D=S({mutationFn:()=>N==="manga"?c.tracker.mangaMalSync.mutate():c.tracker.sync.mutate({provider:"mal"}),onSuccess:f=>{const T=f.summary;u(`Pushed: ${T.pushed} · Pulled: ${T.pulled} · Merged: ${T.merged} · Unchanged: ${T.unchanged}`+(T.errors.length>0?` · ${T.errors.length} error${T.errors.length>1?"s":""}`:""));for(const E of N==="manga"?[[s.trackerStatus],[s.mangaLibrary],[s.mangaContinueReading]]:[[s.trackerStatus],[s.watchlist],[s.continueWatching]])h.invalidateQueries({queryKey:E})},onError:f=>d(f.message)}),x=P?.mal;return e("div",{children:[x?.connected?e(g,{children:[e("div",{className:a.connectedProfile,children:[x.user?.avatar&&e("img",{src:x.user.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:x.user?.name||"MyAnimeList user"}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>M.mutate(),disabled:M.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}),C?e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>D.mutate(),disabled:D.isPending,children:[e(m,{name:"sync-alt",className:D.isPending?a.spin:""}),D.isPending?"Syncing...":"Start Sync"]}),k&&e("div",{className:a.syncSummary,children:k})]}):e("p",{className:a.connectedHint,style:{color:"var(--color-warning)"},children:"Not the active tracker - sync disabled."})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:"Log in with MyAnimeList to enable bidirectional progress & status synchronization."}),e("div",{className:a.credentialFields,children:[e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client ID"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]}),o?.mode==="worker"&&e("span",{className:a.helpText,children:" — defaults to dango's app"})]}),e("input",{className:a.input,placeholder:o?.mode==="worker"?"dango's app (leave empty)":"Client ID",value:t,onChange:f=>y(f.currentTarget.value),autoComplete:"off"})]}),e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client secret"," ",o?.hasSecret&&!b&&e("span",{className:a.helpText,children:"— saved"})]}),e("input",{className:a.input,type:"password",value:b,onChange:f=>l(f.currentTarget.value),placeholder:o?.mode==="worker"?"dango's app (leave empty)":o?.hasSecret?"Saved — leave blank to keep":"Client secret",autoComplete:"new-password"})]})]}),o?.hasCustomId&&o?.hasWorker&&e("button",{className:a.resetBtn,onClick:()=>B.mutate(),disabled:B.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:o?.mode==="worker"?e(g,{children:["By default uses dango's client. To use your own MyAnimeList app: create it at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste its"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above (leave both empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste the"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above. MAL requires the secret even for PKCE apps; it stays on your dango server and is never returned to the browser."]})}),e("button",{className:a.primaryBtn,onClick:()=>p.mutate(),disabled:!(t.trim()&&b.trim()||o?.clientId&&t.trim()===o.clientId&&o.hasSecret||!t.trim()&&!b.trim()&&o?.mode==="worker")||p.isPending,children:p.isPending?"Connecting...":"Connect to MyAnimeList"})]}),L&&e("p",{className:`${a.helpText} ${a.syncErrors}`,role:"alert",children:L}),e("hr",{className:a.divider}),e("p",{className:a.syncHint,children:"You can also import a public list or XML file without connecting an account:"})]})}const In=()=>{const{setIsOpen:N}=aa(),{contentType:C}=na(),h=C==="manga",t=Z();ea.useEffect(()=>{document.title="Trackers - dango"},[]);const[y,b]=i(""),[l,L]=i("username"),[d,k]=i(null),[u,_]=i(!1);ta();const{data:o,isLoading:P}=R({queryKey:[s.trackerStatus],queryFn:async()=>await c.tracker.status.query()}),p=o?.anilist?.connected??!1,M=o?.mal?.connected??!1,{data:B}=R({queryKey:["activeTrackerProvider"],queryFn:async()=>(await c.settings.getByKey.query({key:"active_tracker_provider"}))?.value||""}),D=S({mutationFn:async n=>(await c.settings.set.mutate({key:"active_tracker_provider",value:n}),n),onSuccess:n=>{t.invalidateQueries({queryKey:["activeTrackerProvider"]}),r.success(`Active tracker set to ${n==="mal"?"MyAnimeList":"AniList"}`)},onError:()=>r.error("Failed to update active tracker")}),x=B&&(B==="anilist"&&p||B==="mal"&&M)?B:p&&!M?"anilist":M&&!p?"mal":p?"anilist":"",f=p||M;J(()=>{p&&L("sync")},[p]);const T=S({mutationFn:async()=>(await c.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),k(n),r.success(`Sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}`,{duration:6e3})},onError:n=>r.error(n.message)}),[E,ke]=i(""),[V,fe]=i("sync"),[ce,_e]=i("two-way"),[w,Ue]=i(null),ee=S({mutationFn:async()=>(await c.tracker.mangaSync.mutate({direction:ce})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),Ue(n);const v=(n.warnings?.length??0)>0?`, ${n.warnings.length} warning(s)`:"";r.success(`Manga sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}${v}`,{duration:6e3})},onError:n=>r.error(n.message)}),q=S({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a username");return(await c.tracker.mangaImport.mutate({username:E.trim(),erase:u})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from AniList`),ke("")},onError:n=>r.error(n.message)}),[U,be]=i(""),[ae,ve]=i("username"),[oe,Ne]=i(null),[ne,we]=i(!1),[Ce,le]=i(""),[Ie,Qe]=i(""),j=S({mutationFn:async()=>{if(!U.trim())throw new Error("Please enter a MAL username");const n=await c.tracker.mangaMalImport.mutate({username:U.trim(),erase:u});return{imported:n.imported??0,skipped:n.skipped??0}},onSuccess:({imported:n,skipped:v})=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from MAL${v>0?`, skipped ${v}`:""}`),be("")},onError:n=>r.error(n.message)}),Oe=De(async()=>{const n=document.getElementById("malMangaFile");if(!n.files||n.files.length===0){le("Please select a file first.");return}we(!0),le(""),Ne(null);try{const v=new FormData;v.append("xmlfile",n.files[0]),v.append("erase",String(u));const W=await qe("/api/import/mal-xml-manga",{method:"POST",body:v}),I=await W.json().catch(()=>({}));if(!W.ok)throw new Error(I.error||"Import failed");Ne({imported:I.imported??0,skipped:I.skipped??0}),t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]})}catch(v){le(v.message)}finally{we(!1)}},[u,t]),$=S({mutationFn:async()=>{if(!y.trim())throw new Error("Please enter a username");return(await c.tracker.anilistImport.mutate({username:y.trim(),erase:F})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from AniList`),b("")},onError:n=>r.error(n.message)}),[Q,Se]=i(""),z=S({mutationFn:async n=>{if(!Q.trim())throw new Error("Please enter a MAL username");return(await c.tracker.malImport.mutate({username:Q.trim(),erase:n.erase,useOfflineDb:n.useOfflineDb,skipFallback:n.skipFallback})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from MAL`),Se("")},onError:n=>r.error(n.message)}),[F,Le]=i(!1),[O,He]=i(!0),[H,Ge]=i(!1),[Me,xe]=i(""),[K,Te]=i(!1),[A,Ae]=i(null),[de,ze]=i(null),[Pe,te]=i(""),me=ye(null),We=n=>{n.currentTarget.files&&n.currentTarget.files.length>0?xe(n.currentTarget.files[0].name):xe("")},Xe=De(async()=>{const n=document.getElementById("malFile");if(!n.files||n.files.length===0){te("Please select a file first.");return}const v=n.files[0];Te(!0),Ae(null),ze(null),te("");const W=new AbortController;me.current=W;try{const I=new FormData;I.append("xmlfile",v),I.append("erase",String(F)),I.append("useOfflineDb",String(O)),I.append("skipFallback",String(H));const ue=await qe("/api/import/mal-xml",{method:"POST",body:I,signal:W.signal});if(!ue.ok){const he=await ue.text();let X="Failed to import";try{X=JSON.parse(he).error||X}catch{}throw new Error(X)}const Be=ue.body?.getReader();if(!Be)throw new Error("No response stream");const Ze=new TextDecoder;let pe="",se="";for(;;){const{done:he,value:X}=await Be.read();if(he)break;pe+=Ze.decode(X,{stream:!0});const Ee=pe.split(`
1
+ import{h as J,d as i,A as ye,u as e,S as g,g as ea,q as De}from"./vendor-core-DfaOB3Rn.js";import{u as Z,b as R,a as S}from"./vendor-query-BBT5_sHx.js";import{N as r,q as s,t as c,an as aa,x as na,Z as qe,B as ge}from"./index-CqcwUuWG.js";import{I as m}from"./vendor-icons-C1Pj_eSX.js";function ta(){const N=Z();J(()=>{const C=new URLSearchParams(window.location.search),h=C.get("mal");if(!h)return;const t=C.get("user"),y=C.get("reason");window.history.replaceState(null,"",window.location.pathname),h==="success"?(r.success(t?`Connected to MyAnimeList as ${decodeURIComponent(t)}`:"Connected to MyAnimeList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(y?decodeURIComponent(y):"MyAnimeList authentication failed")},[N])}function sa(){const N=Z(),[C,h]=i(!1);return J(()=>{const t=new URLSearchParams(window.location.search),y=t.get("anilist");if(y){const k=t.get("user"),u=t.get("reason");window.history.replaceState(null,"",window.location.pathname),y==="success"?(r.success(k?`Connected to AniList as ${decodeURIComponent(k)}`:"Connected to AniList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(u?decodeURIComponent(u):"AniList authentication failed");return}const b=new URLSearchParams(window.location.hash.substring(1)),l=b.get("access_token"),L=t.get("code");if(!l&&!L){const k=b.get("error");k&&(r.error(`AniList error: ${k}`),window.history.replaceState(null,"",window.location.pathname));return}const d=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),h(!0),r("Connecting to AniList..."),c.tracker.anilistAuth.mutate(l?{token:l}:{code:L,redirectUri:d}).then(async k=>{const u=k.user;r.success(`Connected to AniList as ${u?.name??"AniList user"}`),N.invalidateQueries({queryKey:[s.trackerStatus]})}).catch(k=>{r.error(k instanceof Error?k.message:"Failed to authenticate with AniList")}).finally(()=>{h(!1)})},[N]),C}const ia="_header_azjok_1",ra="_fadeIn_azjok_1",ca="_pageTitle_azjok_6",oa="_pageSubtitle_azjok_14",la="_importCard_azjok_20",da="_cardHeader_azjok_31",ma="_uploadArea_azjok_49",ua="_fileInputWrapper_azjok_53",pa="_fileInput_azjok_53",ha="_fileDisplay_azjok_71",ga="_fileIcon_azjok_79",ya="_fileName_azjok_84",ka="_browseButton_azjok_93",fa="_optionsArea_azjok_104",_a="_checkboxLabel_azjok_112",ba="_checkbox_azjok_112",va="_checkboxCustom_azjok_125",Na="_optionText_azjok_153",wa="_optionTitle_azjok_159",Ca="_optionDesc_azjok_165",Ia="_actions_azjok_171",Sa="_importBtn_azjok_179",La="_cancelBtn_azjok_185",Ma="_statusMessage_azjok_199",xa="_success_azjok_209",Ta="_error_azjok_215",Aa="_progressSection_azjok_221",za="_progressBar_azjok_226",Pa="_progressFill_azjok_234",ja="_progressInfo_azjok_241",Ba="_progressCount_azjok_248",Ea="_progressTitle_azjok_255",Fa="_sourceBadge_azjok_273",Da="_anilist_azjok_285",qa="_kitsu_azjok_291",$a="_offline_azjok_297",Ka="_skipped_azjok_303",Ra="_cardTitleRow_azjok_308",Ua="_anilistIcon_azjok_318",Qa="_malIcon_azjok_324",Oa="_badgeOnline_azjok_330",Ha="_badgeOffline_azjok_342",Ga="_connectedProfile_azjok_354",Wa="_avatar_azjok_361",Xa="_connectedInfo_azjok_368",Ya="_connectedName_azjok_376",Ja="_connectedHint_azjok_382",Za="_loginPrompt_azjok_387",Va="_loginSection_azjok_395",en="_primaryBtn_azjok_401",an="_fieldLabel_azjok_405",nn="_helpText_azjok_424",tn="_resetBtn_azjok_431",sn="_loginText_azjok_461",rn="_secondaryBtn_azjok_471",cn="_syncBtn_azjok_472",on="_divider_azjok_525",ln="_actionSection_azjok_531",dn="_inputGroup_azjok_545",mn="_credentialFields_azjok_551",un="_credentialField_azjok_551",pn="_input_azjok_545",hn="_syncSummary_azjok_587",gn="_syncErrors_azjok_593",yn="_spin_azjok_597",kn="_radioGroup_azjok_616",fn="_radioLabel_azjok_623",_n="_syncHint_azjok_661",bn="_importLoading_azjok_668",a={header:ia,fadeIn:ra,pageTitle:ca,pageSubtitle:oa,importCard:la,cardHeader:da,uploadArea:ma,fileInputWrapper:ua,fileInput:pa,fileDisplay:ha,fileIcon:ga,fileName:ya,browseButton:ka,optionsArea:fa,checkboxLabel:_a,checkbox:ba,checkboxCustom:va,optionText:Na,optionTitle:wa,optionDesc:Ca,actions:Ia,importBtn:Sa,cancelBtn:La,statusMessage:Ma,success:xa,error:Ta,progressSection:Aa,progressBar:za,progressFill:Pa,progressInfo:ja,progressCount:Ba,progressTitle:Ea,sourceBadge:Fa,anilist:Da,kitsu:qa,offline:$a,skipped:Ka,cardTitleRow:Ra,anilistIcon:Ua,malIcon:Qa,badgeOnline:Oa,badgeOffline:Ha,connectedProfile:Ga,avatar:Wa,connectedInfo:Xa,connectedName:Ya,connectedHint:Ja,loginPrompt:Za,loginSection:Va,primaryBtn:en,fieldLabel:an,helpText:nn,resetBtn:tn,loginText:sn,secondaryBtn:rn,syncBtn:cn,divider:on,actionSection:ln,inputGroup:dn,credentialFields:mn,credentialField:un,input:pn,syncSummary:hn,syncErrors:gn,spin:yn,radioGroup:kn,radioLabel:fn,syncHint:_n,importLoading:bn},ie="tracker_anilist_client_id",Re="49887".trim(),re=!!Re;function $e(){const N=Z(),[C,h]=i(""),t=ye(!1),y=sa(),{data:b}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query()}),{data:l}=R({queryKey:[s.anilistClientId],queryFn:async()=>(await c.settings.getByKey.query({key:ie})).value||""});J(()=>{t.current||l===void 0||(l&&h(l),t.current=!0)},[l]);const L=S({mutationFn:()=>c.tracker.anilistDisconnect.mutate(),onSuccess:()=>{N.invalidateQueries({queryKey:[s.trackerStatus]}),r.success("Disconnected from AniList")},onError:_=>r.error(_.message)}),d=S({mutationFn:()=>c.settings.set.mutate({key:ie,value:""}),onSuccess:()=>{h(""),N.invalidateQueries({queryKey:[s.anilistClientId]}),r.success("Switched to dango's AniList app")},onError:_=>r.error(_.message)}),k=async()=>{const _=C.trim(),o=_||Re;if(!o){r.error("Enter your AniList client ID first");return}const P=(l||"").trim();try{_?_!==l&&await c.settings.set.mutate({key:ie,value:_}):re&&P&&await c.settings.set.mutate({key:ie,value:""}),N.invalidateQueries({queryKey:[s.anilistClientId]})}catch(M){r.error(M.message);return}const p=encodeURIComponent(window.location.origin+window.location.pathname);window.location.href=`https://anilist.co/api/v2/oauth/authorize?client_id=${encodeURIComponent(o)}&response_type=token&state=${p}`},u=b?.anilist?.user??null;return b?.anilist?.connected&&u?e("div",{className:a.connectedProfile,children:[u.avatar&&e("img",{src:u.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:u.name}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>L.mutate(),disabled:L.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:["Log in with AniList to enable bidirectional progress & status synchronization.",y&&e("span",{style:{marginLeft:8,color:"var(--accent)"},children:"Finishing login…"})]}),e("div",{className:a.fieldLabel,children:["AniList client ID - defaults to dango's app"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]})]}),e("div",{className:a.inputGroup,children:[e("input",{type:"text",placeholder:"Client ID",value:C,onChange:_=>h(_.currentTarget.value),className:a.input}),e("button",{className:a.primaryBtn,onClick:k,disabled:!(C.trim()||re),children:[e(m,{name:"external-link-alt"})," Connect"]})]}),re&&l&&e("button",{className:a.resetBtn,onClick:()=>d.mutate(),disabled:d.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:re?e(g,{children:["By default uses dango's client. To use your own AniList app: create it at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste only the ",e("strong",{children:"Client ID"})," above (leave empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste the"," ",e("strong",{children:"Client ID"})," above."]})})]})}function Ke({kind:N="anime",active:C=!0}){const h=Z(),[t,y]=i(""),[b,l]=i(""),[L,d]=i(""),[k,u]=i(""),_=ye(!1),{data:o}=R({queryKey:[s.malClientConfig],queryFn:()=>c.tracker.malConfig.query()}),{data:P}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query(),refetchInterval:15e3});J(()=>{o&&!_.current&&(y(o.clientId),_.current=!0)},[o]);const p=S({mutationFn:async()=>{d(""),(b.trim()||t.trim()&&t.trim()!==o?.clientId)&&await c.tracker.malSaveConfig.mutate({clientId:t.trim(),clientSecret:b.trim()||void 0}),l("");const f=await c.tracker.malLogin.mutate({redirectUri:`${window.location.origin}/api/tracker/mal/callback`});window.location.assign(f.url)},onError:f=>d(f.message)}),M=S({mutationFn:()=>c.tracker.malDisconnect.mutate(),onSuccess:()=>{h.invalidateQueries({queryKey:[s.trackerStatus]}),u(""),d(""),r.success("Disconnected from MyAnimeList")},onError:f=>d(f.message)}),B=S({mutationFn:()=>c.tracker.malClearConfig.mutate(),onSuccess:()=>{y(""),l(""),u(""),d(""),h.invalidateQueries({queryKey:[s.trackerStatus]}),h.invalidateQueries({queryKey:[s.malClientConfig]}),r.success("Switched to dango's MyAnimeList app - reconnect to finish")},onError:f=>d(f.message)}),D=S({mutationFn:()=>N==="manga"?c.tracker.mangaMalSync.mutate():c.tracker.sync.mutate({provider:"mal"}),onSuccess:f=>{const T=f.summary;u(`Pushed: ${T.pushed} · Pulled: ${T.pulled} · Merged: ${T.merged} · Unchanged: ${T.unchanged}`+(T.errors.length>0?` · ${T.errors.length} error${T.errors.length>1?"s":""}`:""));for(const E of N==="manga"?[[s.trackerStatus],[s.mangaLibrary],[s.mangaContinueReading]]:[[s.trackerStatus],[s.watchlist],[s.continueWatching]])h.invalidateQueries({queryKey:E})},onError:f=>d(f.message)}),x=P?.mal;return e("div",{children:[x?.connected?e(g,{children:[e("div",{className:a.connectedProfile,children:[x.user?.avatar&&e("img",{src:x.user.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:x.user?.name||"MyAnimeList user"}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>M.mutate(),disabled:M.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}),C?e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>D.mutate(),disabled:D.isPending,children:[e(m,{name:"sync-alt",className:D.isPending?a.spin:""}),D.isPending?"Syncing...":"Start Sync"]}),k&&e("div",{className:a.syncSummary,children:k})]}):e("p",{className:a.connectedHint,style:{color:"var(--color-warning)"},children:"Not the active tracker - sync disabled."})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:"Log in with MyAnimeList to enable bidirectional progress & status synchronization."}),e("div",{className:a.credentialFields,children:[e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client ID"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]}),o?.mode==="worker"&&e("span",{className:a.helpText,children:" — defaults to dango's app"})]}),e("input",{className:a.input,placeholder:o?.mode==="worker"?"dango's app (leave empty)":"Client ID",value:t,onChange:f=>y(f.currentTarget.value),autoComplete:"off"})]}),e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client secret"," ",o?.hasSecret&&!b&&e("span",{className:a.helpText,children:"— saved"})]}),e("input",{className:a.input,type:"password",value:b,onChange:f=>l(f.currentTarget.value),placeholder:o?.mode==="worker"?"dango's app (leave empty)":o?.hasSecret?"Saved — leave blank to keep":"Client secret",autoComplete:"new-password"})]})]}),o?.hasCustomId&&o?.hasWorker&&e("button",{className:a.resetBtn,onClick:()=>B.mutate(),disabled:B.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:o?.mode==="worker"?e(g,{children:["By default uses dango's client. To use your own MyAnimeList app: create it at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste its"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above (leave both empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste the"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above. MAL requires the secret even for PKCE apps; it stays on your dango server and is never returned to the browser."]})}),e("button",{className:a.primaryBtn,onClick:()=>p.mutate(),disabled:!(t.trim()&&b.trim()||o?.clientId&&t.trim()===o.clientId&&o.hasSecret||!t.trim()&&!b.trim()&&o?.mode==="worker")||p.isPending,children:p.isPending?"Connecting...":"Connect to MyAnimeList"})]}),L&&e("p",{className:`${a.helpText} ${a.syncErrors}`,role:"alert",children:L}),e("hr",{className:a.divider}),e("p",{className:a.syncHint,children:"You can also import a public list or XML file without connecting an account:"})]})}const In=()=>{const{setIsOpen:N}=aa(),{contentType:C}=na(),h=C==="manga",t=Z();ea.useEffect(()=>{document.title="Trackers - dango"},[]);const[y,b]=i(""),[l,L]=i("username"),[d,k]=i(null),[u,_]=i(!1);ta();const{data:o,isLoading:P}=R({queryKey:[s.trackerStatus],queryFn:async()=>await c.tracker.status.query()}),p=o?.anilist?.connected??!1,M=o?.mal?.connected??!1,{data:B}=R({queryKey:["activeTrackerProvider"],queryFn:async()=>(await c.settings.getByKey.query({key:"active_tracker_provider"}))?.value||""}),D=S({mutationFn:async n=>(await c.settings.set.mutate({key:"active_tracker_provider",value:n}),n),onSuccess:n=>{t.invalidateQueries({queryKey:["activeTrackerProvider"]}),r.success(`Active tracker set to ${n==="mal"?"MyAnimeList":"AniList"}`)},onError:()=>r.error("Failed to update active tracker")}),x=B&&(B==="anilist"&&p||B==="mal"&&M)?B:p&&!M?"anilist":M&&!p?"mal":p?"anilist":"",f=p||M;J(()=>{p&&L("sync")},[p]);const T=S({mutationFn:async()=>(await c.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),k(n),r.success(`Sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}`,{duration:6e3})},onError:n=>r.error(n.message)}),[E,ke]=i(""),[V,fe]=i("sync"),[ce,_e]=i("two-way"),[w,Ue]=i(null),ee=S({mutationFn:async()=>(await c.tracker.mangaSync.mutate({direction:ce})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),Ue(n);const v=(n.warnings?.length??0)>0?`, ${n.warnings.length} warning(s)`:"";r.success(`Manga sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}${v}`,{duration:6e3})},onError:n=>r.error(n.message)}),q=S({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a username");return(await c.tracker.mangaImport.mutate({username:E.trim(),erase:u})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from AniList`),ke("")},onError:n=>r.error(n.message)}),[U,be]=i(""),[ae,ve]=i("username"),[oe,Ne]=i(null),[ne,we]=i(!1),[Ce,le]=i(""),[Ie,Qe]=i(""),j=S({mutationFn:async()=>{if(!U.trim())throw new Error("Please enter a MAL username");const n=await c.tracker.mangaMalImport.mutate({username:U.trim(),erase:u});return{imported:n.imported??0,skipped:n.skipped??0}},onSuccess:({imported:n,skipped:v})=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from MAL${v>0?`, skipped ${v}`:""}`),be("")},onError:n=>r.error(n.message)}),Oe=De(async()=>{const n=document.getElementById("malMangaFile");if(!n.files||n.files.length===0){le("Please select a file first.");return}we(!0),le(""),Ne(null);try{const v=new FormData;v.append("xmlfile",n.files[0]),v.append("erase",String(u));const W=await qe("/api/import/mal-xml-manga",{method:"POST",body:v}),I=await W.json().catch(()=>({}));if(!W.ok)throw new Error(I.error||"Import failed");Ne({imported:I.imported??0,skipped:I.skipped??0}),t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]})}catch(v){le(v.message)}finally{we(!1)}},[u,t]),$=S({mutationFn:async()=>{if(!y.trim())throw new Error("Please enter a username");return(await c.tracker.anilistImport.mutate({username:y.trim(),erase:F})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from AniList`),b("")},onError:n=>r.error(n.message)}),[Q,Se]=i(""),z=S({mutationFn:async n=>{if(!Q.trim())throw new Error("Please enter a MAL username");return(await c.tracker.malImport.mutate({username:Q.trim(),erase:n.erase,useOfflineDb:n.useOfflineDb,skipFallback:n.skipFallback})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from MAL`),Se("")},onError:n=>r.error(n.message)}),[F,Le]=i(!1),[O,He]=i(!0),[H,Ge]=i(!1),[Me,xe]=i(""),[K,Te]=i(!1),[A,Ae]=i(null),[de,ze]=i(null),[Pe,te]=i(""),me=ye(null),We=n=>{n.currentTarget.files&&n.currentTarget.files.length>0?xe(n.currentTarget.files[0].name):xe("")},Xe=De(async()=>{const n=document.getElementById("malFile");if(!n.files||n.files.length===0){te("Please select a file first.");return}const v=n.files[0];Te(!0),Ae(null),ze(null),te("");const W=new AbortController;me.current=W;try{const I=new FormData;I.append("xmlfile",v),I.append("erase",String(F)),I.append("useOfflineDb",String(O)),I.append("skipFallback",String(H));const ue=await qe("/api/import/mal-xml",{method:"POST",body:I,signal:W.signal});if(!ue.ok){const he=await ue.text();let X="Failed to import";try{X=JSON.parse(he).error||X}catch{}throw new Error(X)}const Be=ue.body?.getReader();if(!Be)throw new Error("No response stream");const Ze=new TextDecoder;let pe="",se="";for(;;){const{done:he,value:X}=await Be.read();if(he)break;pe+=Ze.decode(X,{stream:!0});const Ee=pe.split(`
2
2
  `);pe=Ee.pop()||"";for(const Y of Ee)if(Y.startsWith("event: "))se=Y.slice(7).trim();else if(Y.startsWith("data: ")){const Ve=Y.slice(6);try{const Fe=JSON.parse(Ve);se==="progress"?Ae(Fe):se==="complete"&&ze(Fe)}catch{}}else Y===""&&(se="")}t.invalidateQueries({queryKey:[s.watchlist]})}catch(I){I instanceof DOMException&&I.name==="AbortError"?te("Import cancelled."):te(I.message)}finally{Te(!1),me.current=null}},[F,O,H,t]),Ye=()=>{me.current?.abort(),c.settings.malImportCancel.mutate().catch(()=>{})},Je=A?Math.round(A.current/A.total*100):0,[G,je]=i("username");return e("div",{className:"page-container",children:[e("div",{className:a.header,children:[e("h1",{className:a.pageTitle,children:"Trackers"}),e("p",{className:a.pageSubtitle,children:"Import & sync your anime watchlists and manga reading lists with tracking services"})]}),e("div",{style:{marginBottom:"16px",fontSize:"0.8rem",color:"var(--color-warning)",borderBottom:"1px solid var(--border-primary)",paddingBottom:"12px"},children:"⚠ Syncing writes directly to your AniList and MyAnimeList entries, and dango may not always handle anime/manga lists correctly - always keep a backup of your lists before syncing."}),f&&e("div",{style:{marginBottom:"16px",display:"flex",alignItems:"center",gap:"10px",fontSize:"0.85rem"},children:[e("label",{htmlFor:"active-tracker-select",style:{fontWeight:600,color:"var(--text-secondary)"},children:"Active tracker:"}),e("select",{id:"active-tracker-select",value:x,onChange:n=>D.mutate(n.currentTarget.value),style:{padding:"0.3rem 0.5rem",borderRadius:"var(--radius-md)",background:"var(--bg-tertiary)",color:"var(--text-primary)",border:"1px solid var(--border-primary)",fontSize:"var(--font-size-sm)",cursor:"pointer"},children:[p&&e("option",{value:"anilist",children:"AniList"}),M&&e("option",{value:"mal",children:"MyAnimeList"})]})]}),!h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"anilist",className:a.anilistIcon}),e("h3",{children:"AniList"}),P?null:p?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e($e,{}),p&&x!=="anilist"&&e("p",{style:{color:"var(--color-warning)",marginTop:"8px",fontSize:"0.85rem"},children:"Not the active tracker - sync disabled."}),p&&x==="anilist"&&e(g,{children:[e("hr",{className:a.divider}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"username",checked:l==="username",onChange:()=>L("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"sync",checked:l==="sync",onChange:()=>L("sync")}),e("span",{children:"Two-way Sync"})]})]}),l==="username"?e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:y,onChange:n=>b(n.currentTarget.value),className:a.input,disabled:$.isPending,onKeyDown:n=>{n.key==="Enter"&&y.trim()&&$.mutate()}})}):e("p",{className:a.syncHint,children:"Merges progress non-destructively: pushes shows and episodes you watched on dango to AniList, and pulls anything you updated on AniList into dango."}),l==="username"&&e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:F,onChange:n=>Le(n.currentTarget.checked),className:a.checkbox,disabled:$.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Erase current watchlist"}),e("span",{className:a.optionDesc,children:"Delete existing watchlist before importing."})]})]})}),l==="username"?e("button",{className:a.syncBtn,onClick:()=>$.mutate(),disabled:!y.trim()||$.isPending,children:[e(m,{name:"download"}),$.isPending?"Importing...":"Start Import"]}):e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>T.mutate(),disabled:T.isPending,children:[e(m,{name:"sync-alt",className:T.isPending?a.spin:""}),T.isPending?"Syncing...":"Start Sync"]}),d&&e("div",{className:a.syncSummary,children:["Pushed: ",d.pushed," · Pulled: ",d.pulled," · Merged:"," ",d.merged," · Unchanged: ",d.unchanged,d.errors.length>0&&e("span",{className:a.syncErrors,children:[" ","· ",d.errors.length," error",d.errors.length>1?"s":""]})]})]})]})]})}),h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"anilist",className:a.anilistIcon}),e("h3",{children:"AniList Manga"}),P?null:p?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e($e,{}),p&&x!=="anilist"&&e("p",{style:{color:"var(--color-warning)",marginTop:"8px",fontSize:"0.85rem"},children:"Not the active tracker - sync disabled."}),p&&x==="anilist"&&e(g,{children:[e("hr",{className:a.divider}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"username",checked:V==="username",onChange:()=>fe("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"sync",checked:V==="sync",onChange:()=>fe("sync")}),e("span",{children:"Two-way Sync"})]})]}),V==="username"?e(g,{children:[e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:E,onChange:n=>ke(n.currentTarget.value),className:a.input,disabled:q.isPending,onKeyDown:n=>{n.key==="Enter"&&E.trim()&&q.mutate()}})}),e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:u,onChange:n=>_(n.currentTarget.checked),className:a.checkbox,disabled:q.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:a.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})})]}):e(g,{children:[e("p",{className:a.syncHint,children:"Merges chapter progress non-destructively: pushes manga and chapters you read on dango to AniList, and pulls anything you updated on AniList into dango. Local titles are linked only on exact title matches, and bookmarks with no chapters read are never pushed."}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"two-way",checked:ce==="two-way",onChange:()=>_e("two-way")}),e("span",{children:"Two-way"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"pull-only",checked:ce==="pull-only",onChange:()=>_e("pull-only")}),e("span",{children:"Pull only (never writes to AniList)"})]})]})]}),V==="username"?e("button",{className:a.syncBtn,onClick:()=>q.mutate(),disabled:!E.trim()||q.isPending,children:[e(m,{name:"download"}),q.isPending?"Importing...":"Start Import"]}):e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>ee.mutate(),disabled:ee.isPending,children:[e(m,{name:"sync-alt",className:ee.isPending?a.spin:""}),ee.isPending?"Syncing...":"Start Manga Sync"]}),w&&e(g,{children:[e("div",{className:a.syncSummary,children:["Pushed: ",w.pushed," · Pulled: ",w.pulled," · Merged: ",w.merged," · Unchanged:"," ",w.unchanged,(w.skipped??0)>0&&e("span",{children:[" · Skipped: ",w.skipped]}),w.errors.length>0&&e("span",{className:a.syncErrors,children:[" ","· ",w.errors.length," error",w.errors.length>1?"s":""]})]}),(w.warnings?.length??0)>0&&e("div",{className:a.syncErrors,style:{marginTop:"8px"},children:[(w.warnings??[]).slice(0,5).map((n,v)=>e("div",{children:["⚠ ",n]},v)),(w.warnings?.length??0)>5&&e("div",{children:["+",(w.warnings?.length??0)-5," more warning(s)"]})]})]})]})]})]})}),!h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"myanimelist",className:a.malIcon}),e("h3",{children:"MyAnimeList"}),P?null:M?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e(Ke,{active:x==="mal"}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"username",checked:G==="username",onChange:()=>je("username")}),e("span",{children:"Username"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"xml",checked:G==="xml",onChange:()=>je("xml")}),e("span",{children:"XML File"})]})]}),G==="username"?e(g,{children:[e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:Q,onChange:n=>Se(n.currentTarget.value),className:a.input,disabled:z.isPending,onKeyDown:n=>{n.key==="Enter"&&Q.trim()&&z.mutate({erase:F,useOfflineDb:O,skipFallback:H})}})}),z.isPending&&e("div",{className:a.importLoading,children:[e(m,{name:"sync-alt",className:a.spin}),e("span",{children:"Importing from MAL..."})]})]}):e("div",{className:a.uploadArea,children:e("div",{className:a.fileInputWrapper,children:[e("input",{type:"file",id:"malFile",accept:".xml,application/xml",className:a.fileInput,onChange:We,disabled:K}),e("div",{className:a.fileDisplay,children:[e(m,{name:"file-alt",className:a.fileIcon}),e("span",{className:a.fileName,children:Me||"Choose XML file..."})]}),e("label",{htmlFor:"malFile",className:a.browseButton,children:"Browse"})]})}),e("div",{className:a.optionsArea,children:[e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:F,onChange:n=>Le(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Erase current watchlist"}),e("span",{className:a.optionDesc,children:"Delete existing watchlist before importing."})]})]}),e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:O,onChange:n=>He(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Use offline database (fast)"}),e("span",{className:a.optionDesc,children:"Match by MAL ID locally first - instant and avoids AniList rate limits."})]})]}),e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:H,onChange:n=>Ge(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Skip online fallback"}),e("span",{className:a.optionDesc,children:"Only import offline matches. Unmatched titles are skipped without API calls."})]})]})]}),G==="username"?e("button",{className:a.syncBtn,onClick:()=>z.mutate({erase:F,useOfflineDb:O,skipFallback:H}),disabled:!Q.trim()||z.isPending,children:[e(m,{name:"download"}),z.isPending?"Importing...":"Start Import"]}):e("div",{className:a.actions,children:K?e(ge,{onClick:Ye,className:a.cancelBtn,children:"Cancel Import"}):e(ge,{onClick:Xe,className:a.importBtn,disabled:!Me,children:[e(m,{name:"upload"})," Start Import"]})}),G==="username"&&z.isError&&e("div",{className:`${a.statusMessage} ${a.error}`,children:z.error.message}),K&&A&&e("div",{className:a.progressSection,children:[e("div",{className:a.progressBar,children:e("div",{className:a.progressFill,style:{width:`${Je}%`}})}),e("div",{className:a.progressInfo,children:[e("span",{className:a.progressCount,children:[A.current," / ",A.total]}),e("span",{className:a.progressTitle,children:A.found?e(g,{children:[A.matchedTitle,e("span",{className:`${a.sourceBadge} ${a[A.source||"anilist"]}`,children:A.source==="kitsu"?"Kitsu":A.source==="offline"?"Offline DB":"AniList"})]}):e("span",{className:a.skipped,children:["Skipped: ",A.title]})})]})]}),de&&e("div",{className:`${a.statusMessage} ${a.success}`,children:["Import complete! Imported: ",de.imported,", Skipped: ",de.skipped,"."]}),Pe&&e("div",{className:`${a.statusMessage} ${a.error}`,children:Pe})]})}),h&&e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"myanimelist",className:a.malIcon}),e("h3",{children:"MyAnimeList Manga"}),P?null:M?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e(Ke,{kind:"manga",active:x==="mal"}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"username",checked:ae==="username",onChange:()=>ve("username")}),e("span",{children:"Username"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"xml",checked:ae==="xml",onChange:()=>ve("xml")}),e("span",{children:"XML File"})]})]}),ae==="username"?e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:U,onChange:n=>be(n.currentTarget.value),className:a.input,disabled:j.isPending,onKeyDown:n=>{n.key==="Enter"&&U.trim()&&j.mutate()}})}):e("div",{className:a.uploadArea,children:e("div",{className:a.fileInputWrapper,children:[e("input",{type:"file",id:"malMangaFile",accept:".xml,application/xml",className:a.fileInput,onChange:n=>Qe(n.currentTarget.files?.[0]?.name??""),disabled:ne}),e("div",{className:a.fileDisplay,children:[e(m,{name:"file-alt",className:a.fileIcon}),e("span",{className:a.fileName,children:Ie||"Choose XML file..."})]}),e("label",{htmlFor:"malMangaFile",className:a.browseButton,children:"Browse"})]})}),e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:u,onChange:n=>_(n.currentTarget.checked),className:a.checkbox,disabled:j.isPending||ne}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:a.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})}),ae==="username"?e("button",{className:a.syncBtn,onClick:()=>j.mutate(),disabled:!U.trim()||j.isPending,children:[e(m,{name:"download"}),j.isPending?"Importing...":"Start Import"]}):e("div",{className:a.actions,children:e(ge,{onClick:Oe,className:a.importBtn,disabled:ne||!Ie,children:[e(m,{name:"upload"})," ",ne?"Importing...":"Start Import"]})}),j.isError&&e("div",{className:`${a.statusMessage} ${a.error}`,children:j.error.message}),Ce&&e("div",{className:`${a.statusMessage} ${a.error}`,children:Ce}),oe&&e("div",{className:`${a.statusMessage} ${a.success}`,children:["Import complete! Imported: ",oe.imported,", Skipped:"," ",oe.skipped,"."]}),e("p",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginTop:"8px"},children:"MAL manga is matched to AniList by MAL ID with a title fallback. Unmatched titles are skipped. Imports land as AniList-linked entries alongside your provider bookmarks."})]})]})};export{In as default};
@@ -0,0 +1,4 @@
1
+ import{u as t,d as y,A as H,h as C,S as xe,g as qr,q as N,o as Kr,p as Yr,a as Qr,T as _e}from"./vendor-core-DfaOB3Rn.js";import{j as on,p as F,t as ot,ab as jr,a7 as Gr,g as Xr,V as hs,h as Zr,ai as Jr,N as Qs,B as Se,F as eo}from"./index-CqcwUuWG.js";import{P as to,a as no,b as so,F as ro,d as oo,c as ao}from"./PlayerProvider-BPOUTsvo.js";import{u as io}from"./vendor-query-BBT5_sHx.js";import{I as pe}from"./vendor-icons-C1Pj_eSX.js";import{C as lo,P as co}from"./PlayerSurface-DRZlkk9L.js";import{p as vs,M as uo,x as Js,f as bs,b as mo,C as ho,a as An,u as po,h as vo,i as bo,m as fo,g as go,j as yo,l as _o,k as So,s as xn,c as Co,d as To,e as ko,r as No,n as De,A as Eo,q as wo,E as Io,v as Ao,P as xo,t as ne,w as Po,R as Mo,o as js}from"./useWatchAlongPlayer-DC5cqK1c.js";import{S as Lo}from"./SettingsShell-ByVlsU3X.js";import{O as Pn,S as Ro,a as $o,A as Bo,b as Oo}from"./AmbientLightMenu-CO10UIKM.js";import{M as Do}from"./MatureConsentModal-D2QxzAd5.js";import{e as Fo,b as zo,f as Vo,g as Uo,d as Wo,c as Ho,h as qo,i as Ko}from"./useTvLibrary-D9vDuZs7.js";import{b as Yo,i as rn,l as Qo,a as jo,c as Go,h as Gs}from"./playbackCompletion-DasRrCt1.js";import{u as Xo}from"./useIsMobile-Dvx1uJ82.js";import{S as Zo}from"./SynopsisText-B3Sa5pRv.js";import{W as Jo}from"./WatchAlongPanel-D_ToyGjh.js";import"./libraryInvalidation-CC9NocI9.js";const ea="_fullscreenFlat_n2elb_1",ta="_timeDisplay_n2elb_12",na="_bottomControls_n2elb_16",sa="_leftControls_n2elb_20",ra="_rightControls_n2elb_21",oa="_controlBtn_n2elb_25",aa="_controlsOverlay_n2elb_32",ia="_hidden_n2elb_52",la="_topControls_n2elb_58",ca="_backBtn_n2elb_78",da="_videoTitleInfo_n2elb_98",ua="_animeTitle_n2elb_104",ma="_episodeLabel_n2elb_112",ha="_speedBoostBadge_n2elb_119",pa="_progressBarContainer_n2elb_165",va="_progressBar_n2elb_165",ba="_thumb_n2elb_184",fa="_bufferedBar_n2elb_202",ga="_watchedBar_n2elb_212",ya="_scrubbing_n2elb_237",_a="_timeBubble_n2elb_241",Sa="_bottomControlsRow_n2elb_255",Ca="_nextEpisodeBtn_n2elb_278",Ta="_active_n2elb_340",ka="_settingsPanel_n2elb_352",Na="_settingsHeader_n2elb_371",Ea="_settingsBackBtn_n2elb_379",wa="_settingsTitle_n2elb_397",Ia="_settingsContent_n2elb_408",Aa="_currentValue_n2elb_417",xa="_menuItem_n2elb_423",Pa="_menuNote_n2elb_456",Ma="_loadingOverlay_n2elb_465",La="_loadingDots_n2elb_476",Ra="_dot_n2elb_481",$a="_bufferingOverlay_n2elb_510",Ba="_bufferingSpinner_n2elb_519",o={fullscreenFlat:ea,timeDisplay:ta,bottomControls:na,leftControls:sa,rightControls:ra,controlBtn:oa,controlsOverlay:aa,hidden:ia,topControls:la,backBtn:ca,videoTitleInfo:da,animeTitle:ua,episodeLabel:ma,speedBoostBadge:ha,progressBarContainer:pa,progressBar:va,thumb:ba,bufferedBar:fa,watchedBar:ga,scrubbing:ya,timeBubble:_a,bottomControlsRow:Sa,nextEpisodeBtn:Ca,active:Ta,settingsPanel:ka,settingsHeader:Na,settingsBackBtn:Ea,settingsTitle:wa,settingsContent:Ia,currentValue:Aa,menuItem:xa,menuNote:Pa,loadingOverlay:Ma,loadingDots:La,dot:Ra,bufferingOverlay:$a,bufferingSpinner:Ba},Oa=({player:r,visible:f,settingsOpen:U,onOpenSettings:L,onCloseSettings:R,hasSubtitles:I,isSubtitleActive:P,subtitles:d,onSubtitleChange:i,showNextEpisodeButton:w,onNextEpisode:s,isTheaterMode:$,onTheaterModeToggle:le,timeLabelRef:ce})=>{const{state:Pe,actions:at}=r,Me=()=>{if(P){i(-1);return}let Ce=null;try{Ce=F.getItem("tvLastSubtitle")}catch{}i(vs(d,{lastKey:Ce,enabled:!0}))};return t("div",{className:`${o.controlsOverlay} ${f?"":o.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:o.bottomControls,onClick:Ce=>Ce.stopPropagation(),children:[t(to,{classes:{container:o.progressBarContainer,scrubbing:o.scrubbing,timeBubble:o.timeBubble,bar:o.progressBar,buffered:o.bufferedBar,watched:o.watchedBar,thumb:o.thumb},timeLabelRef:ce}),t("div",{className:o.bottomControlsRow,children:[t("div",{className:o.leftControls,children:[t(no,{className:o.controlBtn}),t(so,{buttonClassName:o.controlBtn,onExpandedChange:at.setShowVolumeSlider}),t("span",{className:o.timeDisplay,ref:ce,children:[on(0)," / ",on(Pe.duration)]})]}),t("div",{className:o.rightControls,children:[w&&t("button",{className:o.nextEpisodeBtn,onClick:s,title:"Play next episode",children:"Next EP"}),I&&t("button",{className:`${o.controlBtn} ${P?o.active:""}`,onClick:Me,"aria-label":P?"Turn subtitles off":"Turn subtitles on",children:t(pe,{name:"closed-captioning"})}),t("button",{className:`${o.controlBtn} ${U?o.active:""}`,onClick:()=>U?R():L(),"aria-label":"Settings",children:t(pe,{name:"cog"})}),t("button",{className:`${o.controlBtn} ${$?o.active:""}`,onClick:Ce=>{Ce.stopPropagation(),le()},title:$?"Exit Theater Mode":"Theater Mode","aria-label":$?"Exit Theater Mode":"Theater Mode",children:t(pe,{name:"tv"})}),t(ro,{className:o.controlBtn})]})]})]})})},Mn=-6e4,ps=6e4,Xs=500,Da=({classes:r,delayMs:f,onDelayChange:U})=>{const[L,R]=y(null),I=L??f,P=H(U);P.current=U;const d=H(f);d.current=f;const i=H(null);i.current=L,C(()=>{R(null)},[f]),C(()=>()=>{const $=i.current;$!==null&&$!==d.current&&P.current($)},[]);const w=$=>{d.current=$,i.current=null,P.current($),R(null)},s=$=>{const le=i.current??d.current,ce=Math.max(Mn,Math.min(ps,le+$));w(ce)};return t(xe,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:r.item,onClick:()=>s(-Xs),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:r.item,onClick:()=>s(Xs),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:r.item,onClick:()=>w(0),disabled:I===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(uo,{label:"Subtitle timing",display:Js(I),min:Mn,max:ps,step:100,value:I,percent:(I-Mn)/(ps-Mn)*100,onChange:$=>{const le=Math.round($);i.current=le,R(le)},onCommit:()=>{const $=i.current;$!==null&&w($)}}),t("div",{className:r.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},Fa=({view:r,onSelectView:f,onClose:U,player:L,onSubtitleStyleChange:R,streams:I,resolutionIdx:P,onResolutionChange:d,hasSubtitles:i,subtitles:w,selectedSubtitle:s,isSubtitleActive:$,onSubtitleChange:le,audioTracks:ce,selectedAudioTrack:Pe,onAudioTrackChange:at,videoDelayEnabled:Me,onVideoDelayToggle:Ce,videoDelayMs:Fe,onVideoDelayChange:u,onCalibrate:Ke,subtitleDelayMs:it,onSubtitleDelayChange:Mt,ambientSettings:ve,onAmbientChange:b,onOpenSubtitles:lt,openSubLanguages:Ye,openSubFiles:T,openSubLoading:z,openSubError:oe,onOpenSubLangSelect:Nt,onOpenSubFileSelect:Lt})=>{const{state:K}=L,ct=()=>t(xe,{children:[I.length>1&&t("button",{className:o.menuItem,onClick:()=>f("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:o.currentValue,children:I[P]?.quality||"Auto"})]}),(i||lt)&&t("button",{className:o.menuItem,onClick:()=>f("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:o.currentValue,children:$?w[s]?.label||w[s]?.language:"Off"})]}),i&&t("button",{className:o.menuItem,onClick:()=>f("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:o.currentValue,children:[K.subtitleFontSize.toFixed(1),"x · ",K.subtitlePosition]})]}),i&&t("button",{className:o.menuItem,onClick:()=>f("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:o.currentValue,children:Js(it)})]}),ce.length>0&&t("button",{className:o.menuItem,onClick:()=>f("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:o.currentValue,children:ce[Pe]?.label||ce[Pe]?.language})]}),t("button",{className:o.menuItem,onClick:()=>f("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:o.currentValue,children:Me?`${Fe}ms`:"Off"})]}),ve&&b&&t("button",{className:o.menuItem,onClick:()=>f("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:o.currentValue,children:ve.enabled?"On":"Off"})]})]}),Et=()=>t(Pn,{classes:{item:o.menuItem,active:o.active},options:I.map((p,Y)=>({key:String(Y),label:p.quality,selected:Y===P})),onSelect:p=>d(Number(p))}),Rt=()=>t(xe,{children:[t("button",{type:"button",className:`${o.menuItem} ${$?"":o.active}`,onClick:()=>le(-1),children:t("span",{children:"Off"})}),lt&&t("button",{type:"button",className:o.menuItem,onClick:lt,children:t("span",{children:"Open Subtitles..."})}),w.map((p,Y)=>t("button",{type:"button",className:`${o.menuItem} ${Y===s?o.active:""}`,onClick:()=>le(Y),children:t("span",{children:p.label||p.language})},Y))]}),$t=()=>t(xe,{children:[z&&t("div",{className:o.menuNote,children:"Loading languages..."}),!z&&oe&&t("div",{className:o.menuNote,children:oe}),!z&&!oe&&(Ye?.length??0)===0&&t("div",{className:o.menuNote,children:"No languages found"}),!z&&(Ye?.length??0)>0&&t(Pn,{classes:{item:o.menuItem,active:o.active},options:(Ye||[]).map((p,Y)=>({key:String(p.id||p.language||Y),label:`${p.label||p.language||p.id}${p.count?` (${p.count})`:""}`,selected:!1})),onSelect:p=>Nt?.(p)})]}),de=()=>t(xe,{children:[z&&t("div",{className:o.menuNote,children:"Loading files..."}),!z&&oe&&t("div",{className:o.menuNote,children:oe}),!z&&!oe&&(T?.length??0)===0&&t("div",{className:o.menuNote,children:"No files found"}),!z&&(T?.length??0)>0&&t(Pn,{classes:{item:o.menuItem,active:o.active},options:(T||[]).map(p=>({key:p.id,label:p.label,selected:!1})),onSelect:p=>{const Y=(T||[]).find(ut=>String(ut.id)===p);Y&&Lt?.({...Y,language:Y.language||"en"})}})]}),ue=()=>t(Ro,{classes:{item:o.menuItem,active:o.active},values:{font:K.subtitleFont,fontSize:K.subtitleFontSize,position:K.subtitlePosition,bgOpacity:K.subtitleBgOpacity,bgColor:K.subtitleBgColor,textColor:K.subtitleTextColor,edge:K.subtitleEdge,outlineWidth:K.subtitleOutlineWidth,outlineColor:K.subtitleOutlineColor,bold:K.subtitleBold},onChange:R,onFontMenu:()=>f("subtitle-font")}),dt=()=>t($o,{classes:{item:o.menuItem,active:o.active},value:K.subtitleFont,onChange:p=>R("font",p)}),ze=()=>t(Da,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},delayMs:it,onDelayChange:p=>Mt?.(p)}),be=()=>t(Pn,{classes:{item:o.menuItem,active:o.active},options:ce.map((p,Y)=>({key:String(Y),label:p.label||p.language,selected:Y===Pe})),onSelect:p=>at(Number(p))}),Te=()=>t(Bo,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},enabled:Me,delayMs:Fe,onToggle:p=>Ce?.(p),onDelayChange:p=>u?.(p),onCalibrate:Ke}),ke=()=>ve&&b?t(Oo,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},values:ve,onChange:b}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:p=>p.stopPropagation(),children:t(Lo,{classes:{panel:o.settingsPanel,header:o.settingsHeader,backBtn:o.settingsBackBtn,title:o.settingsTitle,content:o.settingsContent},title:r==="main"?"Settings":r==="subtitle-font"?"Subtitle Font":r==="subtitle-style"?"Subtitle Style":r==="subtitle-timing"?"Subtitle Timing":r==="audio"?"Audio Track":r==="resolution"?"Resolution":r==="av-sync"?"A/V Sync":r==="ambient"?"Ambient Light":r==="opensub-langs"?"Open Subtitles":r==="opensub-files"?"Select File":r.charAt(0).toUpperCase()+r.slice(1),onBack:()=>{if(r==="main")return U();if(r==="subtitle-font")return f("subtitle-style");if(r==="opensub-files")return f("opensub-langs");f("main")},children:[r==="main"&&ct(),r==="resolution"&&Et(),r==="subtitles"&&Rt(),r==="subtitle-style"&&ue(),r==="subtitle-font"&&dt(),r==="subtitle-timing"&&ze(),r==="audio"&&be(),r==="av-sync"&&Te(),r==="ambient"&&ke(),r==="opensub-langs"&&$t(),r==="opensub-files"&&de()]})})},za=({player:r,title:f,episodeLabel:U,server:L,audioTracks:R,selectedAudioTrack:I,onAudioTrackChange:P,subtitles:d,selectedSubtitle:i,onSubtitleChange:w,streams:s,resolutionIdx:$,onResolutionChange:le,onBack:ce,children:Pe,videoDelayEnabled:at=!1,onVideoDelayToggle:Me,videoDelayMs:Ce=0,onVideoDelayChange:Fe,onCalibrateAvSync:u,subtitleDelayMs:Ke=0,onSubtitleDelayChange:it,showNextEpisodeButton:Mt=!1,onNextEpisode:ve,isLoading:b=!1,isTheaterMode:lt,onTheaterModeToggle:Ye,ambientSettings:T,onAmbientChange:z,hideChrome:oe=!1,onOpenSubtitles:Nt,openSubLanguages:Lt,openSubFiles:K,openSubLoading:ct,openSubError:Et,onOpenSubLangSelect:Rt,onOpenSubFileSelect:$t})=>{const{state:de,refs:ue,actions:dt}=r,ze=ue.videoRef,{subtitleFont:be,subtitleFontSize:Te,subtitlePosition:ke,subtitleBgOpacity:p,subtitleBgColor:Y,subtitleTextColor:ut,subtitleEdge:Ve,subtitleOutlineWidth:wt,subtitleOutlineColor:Ee,subtitleBold:mt}=de,[se,fe]=y(null),Ln=H(null),[Bt,Rn]=y(0);C(()=>{const G=ze.current;if(!G)return;const E=()=>Rn(G.clientHeight||0);E();const je=new ResizeObserver(E);return je.observe(G),()=>je.disconnect()},[ze]);const Ot=dt.setSubtitleStyle;C(()=>{const G="tv-player-subtitle-style";let E=document.getElementById(G);E||(E=document.createElement("style"),E.id=G,document.head.appendChild(E));const je={font:be,fontSize:Te,position:ke,bgOpacity:p,bgColor:Y,textColor:ut,edge:Ve,outlineWidth:wt,outlineColor:Ee,bold:mt},ae=ze.current,Re=bs(Te,Bt||ae?.clientHeight||720);if(E.textContent=mo({...je,fontSize:Re}),ae){const zt=()=>{const B=Number(ke);return isNaN(B)?0:Math.max(0,Math.min(100,B))},Vt=(B,re)=>{try{const ie=B;ie.snapToLines=!1,ie.line=re}catch{}},Ut=()=>{const B=Re*16,re=ae.videoHeight||ae.clientHeight||720,ie=ae.videoWidth||ae.clientWidth||1280;return{step:B*1.3/re*100,chars:Math.max(20,Math.floor(ie/(B*.55)))}},Wt=B=>{const re=Math.max(0,Math.min(100,100-zt())),ie=Array.from(B.activeCues??[]);if(ie.length<=1){ie.forEach(Z=>Vt(Z,re));return}const{step:m,chars:h}=Ut();let ge=re;for(let Z=ie.length-1;Z>=0;Z--){const dn=String(ie[Z].text??"").replace(/<[^>]*>/g,"").split(`
2
+ `).reduce((Kt,Dn)=>Kt+Math.max(1,Math.ceil(Dn.length/h)),0),qt=ge-dn*m;Vt(ie[Z],Math.max(0,qt)),ge=qt-m*.4}},bt=()=>{const B=Math.max(0,Math.min(100,100-zt()));Array.from(ae.textTracks).forEach(re=>{re.cues&&(Array.from(re.cues).forEach(ie=>Vt(ie,B)),re.mode==="showing"&&Wt(re))})};bt();const me=B=>{const re=B.target;re.mode==="showing"&&Wt(re)},cn=()=>{Array.from(ae.textTracks).forEach(B=>{B.removeEventListener("cuechange",me),B.addEventListener("cuechange",me)}),bt()};Array.from(ae.textTracks).forEach(B=>{B.addEventListener("cuechange",me)}),ae.textTracks.addEventListener("addtrack",cn);const Ue=Array.from(ae.querySelectorAll("track")),Ht=()=>bt();return Ue.forEach(B=>B.addEventListener("load",Ht)),()=>{Array.from(ae.textTracks).forEach(B=>{B.removeEventListener("cuechange",me)}),ae.textTracks.removeEventListener("addtrack",cn),Ue.forEach(B=>B.removeEventListener("load",Ht))}}},[be,Te,ke,p,Y,ut,Ve,wt,Ee,mt,i,d,ze,Bt]);const an=d.length>0||!!Nt,ht=i>=0,$n=()=>{fe("main"),dt.setShowControls(!0)},we=()=>{fe(null)},Le=de.showControls||!!se,Qe=oo(r.engine),pt=Qe.audioTracks.find(G=>G.id===Qe.activeAudioTrack)??R[I],ln=i>=0?d[i]??Qe.subtitleTracks.find(G=>G.id===i):void 0,Dt=t(ho,{visible:Le,title:f,episode:U,server:b?void 0:L,audio:b?void 0:pt?.label||pt?.language,subtitles:b?void 0:ln?.label||ln?.language,onBack:ce,classes:{overlay:o.controlsOverlay,hidden:o.hidden,top:o.topControls,backBtn:o.backBtn,titleInfo:o.videoTitleInfo,title:o.animeTitle,episode:o.episodeLabel}}),vt=!b&&!de.isBuffering&&de.duration>0?t(lo,{}):null,Bn=t(Oa,{player:r,visible:Le,settingsOpen:!!se,onOpenSettings:$n,onCloseSettings:we,hasSubtitles:an,isSubtitleActive:ht,subtitles:d,onSubtitleChange:w,showNextEpisodeButton:Mt,onNextEpisode:ve,isTheaterMode:lt,onTheaterModeToggle:Ye,timeLabelRef:Ln}),Ft=se?t(Fa,{view:se,onSelectView:fe,onClose:we,player:r,onSubtitleStyleChange:Ot,streams:s,resolutionIdx:$,onResolutionChange:le,hasSubtitles:an,subtitles:d,selectedSubtitle:i,isSubtitleActive:ht,onSubtitleChange:w,audioTracks:R,selectedAudioTrack:I,onAudioTrackChange:P,videoDelayEnabled:at,onVideoDelayToggle:Me,videoDelayMs:Ce,onVideoDelayChange:Fe,onCalibrate:()=>{fe(null),u?.()},subtitleDelayMs:Ke,onSubtitleDelayChange:it,ambientSettings:T,onAmbientChange:z,onOpenSubtitles:()=>{Nt?.(),fe("opensub-langs")},openSubLanguages:Lt,openSubFiles:K,openSubLoading:ct,openSubError:Et,onOpenSubLangSelect:G=>{Rt?.(G),fe("opensub-files")},onOpenSubFileSelect:G=>{$t?.(G),we()}}):null,j=t(xe,{children:[b&&t("div",{className:o.loadingOverlay,"aria-hidden":"true",children:t("div",{className:o.loadingDots,children:[t("div",{className:o.dot}),t("div",{className:o.dot}),t("div",{className:o.dot})]})}),de.isBuffering&&!b&&t("div",{className:o.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:o.bufferingSpinner})}),de.isSpeedBoostActive&&t("div",{className:o.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(pe,{name:"forward",size:12})]})]});return t(co,{engine:r.engine,topBar:Dt,centerControls:vt,bottomBar:!b&&de.duration>0?Bn:null,settingsPanel:Ft,overlays:j,isInteracting:!!se||de.showVolumeSlider,nativeControls:de.useNativeControls,onStageClick:we,className:de.isFullscreen?o.fullscreenFlat:"",chromeDisabled:oe,children:Pe})},Va=({servers:r,selectedServer:f,onServerSelect:U})=>r.length===0?null:t("div",{className:An.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:An.sourceButtons,children:r.map(L=>t("button",{className:`${An.sourceButton} ${f===L?An.active:""}`,onClick:()=>U(L),children:L},L))})]}),Ua=qr.memo(Va);function Wa({details:r,isMovie:f,season:U,episode:L,videoRef:R,active:I}){const P=H("");P.current||(P.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const d=N(()=>{if(!r)return;const i=R.current,w=f?"":`S${String(U).padStart(2,"0")}E${String(L).padStart(2,"0")}`;ot.discord.tvPresence.mutate({title:r.title,episodeLabel:w,isPlaying:i?!i.paused&&!i.ended:!0,thumbnail:r.poster,currentTime:i?i.currentTime:0,duration:i&&i.duration||0,isAdult:r.adult===!0,sessionId:P.current}).catch(()=>{}),ot.discord.heartbeat.mutate({sessionId:P.current}).catch(()=>{})},[r,f,U,L,R]);return C(()=>{if(!r)return;d();const i=window.setInterval(()=>{const w=R.current;(!w||!w.paused)&&d()},15e3);return()=>window.clearInterval(i)},[d,r,R]),C(()=>{if(!r||!I)return;const i=R.current;if(!i)return;const w=()=>d();return i.addEventListener("play",w),i.addEventListener("pause",w),i.addEventListener("seeked",w),()=>{i.removeEventListener("play",w),i.removeEventListener("pause",w),i.removeEventListener("seeked",w)}},[r,I,d,R]),C(()=>{const i=P.current,w=()=>jr(i),s=()=>w();return window.addEventListener("pagehide",s),window.addEventListener("beforeunload",s),()=>{window.removeEventListener("pagehide",s),window.removeEventListener("beforeunload",s),w()}},[]),{sendPresence:d}}function Ha(r,f,U){const L=()=>{const I=Array.isArray(r.audioTracks)?r.audioTracks.length:0,P=U.getWant(),d=I>0?Math.min(Math.max(0,P),I-1):P;r.audioTrack=d,d!==P&&U.onResolve(d)},R=(I,P)=>{const d=U.getWant(),i=Array.isArray(r.audioTracks)?r.audioTracks.length:0;if(P.id!==d&&d>=0&&d<i){r.audioTrack!==d&&(r.audioTrack=d);return}U.onResolve(P.id)};return r.on(f.MANIFEST_PARSED,L),r.on(f.AUDIO_TRACK_SWITCHED,R),()=>{r.off(f.MANIFEST_PARSED,L),r.off(f.AUDIO_TRACK_SWITCHED,R)}}const qa=/\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 Ka(){try{if(qa.test(navigator.userAgent||""))return!0;const r=navigator.deviceMemory;if(typeof r=="number"&&r>0&&r<2)return!0}catch{}return!1}const Ya="_statusMsg_vmhzm_1",Qa="_error_vmhzm_7",ja="_spinner_vmhzm_11",Ga="_spin_vmhzm_11",Xa="_sourceLoader_vmhzm_16",Za="_ringSpinner_vmhzm_22",Ja="_meta_vmhzm_40",ei="_year_vmhzm_48",ti="_rating_vmhzm_53",ni="_typeBadge_vmhzm_62",si="_tv_vmhzm_70",ri="_movie_vmhzm_75",oi="_controlLabel_vmhzm_80",ai="_select_vmhzm_90",ii="_playerSection_vmhzm_102",li="_video_vmhzm_106",ci="_videoHidden_vmhzm_128",di="_delayCanvas_vmhzm_133",ui="_delayCanvasActive_vmhzm_146",mi="_subtitleOverlay_vmhzm_150",hi="_videoIframe_vmhzm_169",pi="_retryButton_vmhzm_177",vi="_sidebarSeason_vmhzm_192",bi="_mobileSeasonRow_vmhzm_208",fi="_providerActions_vmhzm_221",gi="_providerRow_vmhzm_228",yi="_autoplayActive_vmhzm_247",_i="_genreRow_vmhzm_258",Si="_genreChip_vmhzm_265",Ci="_metaRow_vmhzm_275",Ti="_detailGrid_vmhzm_284",ki="_detailItem_vmhzm_292",Ni="_imdbLink_vmhzm_314",Ei="_watchedOverlay_vmhzm_324",wi="_watchedTitle_vmhzm_346",Ii="_watchedSubtext_vmhzm_352",Ai="_watchedActions_vmhzm_358",xi="_watchedActionsCentered_vmhzm_376",S={statusMsg:Ya,error:Qa,spinner:ja,spin:Ga,sourceLoader:Xa,ringSpinner:Za,meta:Ja,year:ei,rating:ti,typeBadge:ni,tv:si,movie:ri,controlLabel:oi,select:ai,playerSection:ii,video:li,videoHidden:ci,delayCanvas:di,delayCanvasActive:ui,subtitleOverlay:mi,videoIframe:hi,retryButton:pi,sidebarSeason:vi,mobileSeasonRow:bi,providerActions:fi,providerRow:gi,autoplayActive:yi,genreRow:_i,genreChip:Si,metaRow:Ci,detailGrid:Ti,detailItem:ki,imdbLink:Ni,watchedOverlay:Ei,watchedTitle:wi,watchedSubtext:Ii,watchedActions:Ai,watchedActionsCentered:xi},Pi=[],Mi=[];function Zs({error:r,onRetry:f}){return t("div",{className:`${S.statusMsg} ${S.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:r}),t("button",{className:S.retryButton,onClick:f,children:"Retry"})]})})}const ji=()=>{const{id:r}=Kr(),[f]=Yr(),U=H(f);U.current=f;const L=Qr(),R=io(),I=f.get("type"),P=Gr(),d=!!P.session,i=d&&!P.session?.host,w=i&&["tv","movie"].includes(P.room?.selection.kind||"")?P.room?.selection:null,[s,$]=y(null),[le,ce]=y(null),[Pe,at]=y(()=>Date.now()),Me=(le??s?.next_episode_to_air??null)?.air_timestamp;C(()=>{if(typeof Me!="number"||Me<=Date.now())return;const e=setInterval(()=>at(Date.now()),1e3);return()=>clearInterval(e)},[Me]);const[Ce,Fe]=y(()=>parseInt(f.get("s")||"1",10)||1),u=w?.season??Ce,[Ke,it]=y([]),[Mt,ve]=y(()=>parseInt(f.get("e")||"1",10)||1),b=w?Number(w.episode):Mt,[lt,Ye]=y(()=>{try{return F.getItem("tvProvider")||""}catch{return""}}),T=w?.provider??lt,[z,oe]=y([]),[Nt,Lt]=y(""),[K,ct]=y(""),{options:Et,isFallback:Rt,isLoading:$t}=Xr(),de=_e(()=>Et.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.id,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[Et]),ue=Rt||de.length===0?Pi:de,dt=ue.filter(e=>e.tier==="direct"),ze=ue.filter(e=>e.tier==="embed"),[be,Te]=y(!1),[ke,p]=y(""),[Y,ut]=y([]),[Ve,wt]=y(0),[Ee,mt]=y([]),[se,fe]=y(-1),[Ln,Bt]=y([]),[Rn,Ot]=y([]),[an,ht]=y(!1),[$n,we]=y(null),[Le,Qe]=y(0),[pt,ln]=y(""),[Dt,vt]=y(""),[Bn,Ft]=y(()=>{try{return F.getItem("tvServer")||""}catch{return""}}),j=w?.source??Bn,G=_e(()=>ue.find(e=>e.id===T),[ue,T]),E=G?.tier==="embed",[je,ae]=y([]),[Re,zt]=y(""),[Vt,Ut]=y(""),[Wt,bt]=y(!1),me=_e(()=>je.length>0?je:G?.servers??[],[je,G]),cn=_e(()=>Re&&!d?["Embed",...me]:me,[me,Re,d]),Ue=Wt&&!!Re,Ht=Ue?Vt||Re:"";C(()=>{if(!Re){Ut("");return}let e=!1;return hs(`/api/resolve?url=${encodeURIComponent(Re)}`).then(n=>{!e&&n.finalUrl&&Ut(n.finalUrl)}).catch(()=>{}),()=>{e=!0}},[Re]);const B=H([]);C(()=>{B.current=z},[z]);const re=H(Ve);C(()=>{re.current=Ve},[Ve]);const ie=H(se);C(()=>{ie.current=se},[se]);const m=po({skipIntervals:Mi}),h=m.refs.videoRef,ge=H(null),Z=H([]),On=H(null),dn=H(null),{videoDelayMs:qt,videoDelayEnabled:Kt,setDelayEnabled:Dn,handleVideoDelayChange:fs,isCalibrating:er,testClipActive:Ie,stopCalibration:Fn,openAvSyncCalibrator:tr,cancelAvSyncCalibrator:nr,applyAvSyncCalibrator:sr,toggleTestClip:rr,calibReturnRef:un,effectiveVideoDelayMs:zn}=vo(h),[It,or]=y(()=>{try{const e=Number(F.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),Vn=H(It);Vn.current=It;const ar=N(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(Vn.current!==n){Vn.current=n,or(n);try{F.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);bo({videoRef:h,canvasRef:On,delayMs:zn,enabled:Kt});const Un=Kt,Ne=Un||It!==0,{settings:Wn,update:ir}=fo(),Hn=H(Ne);Hn.current=Ne;const qn=N(()=>{if(!Hn.current)return;const e=h.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[h]),{hasConsent:Yt,grant:lr}=Zr(),v=I==="movie";Wa({details:s,isMovie:v,season:u,episode:b,videoRef:h,active:!E&&!be&&!ke&&z.length>0});const mn=r?Jr(I||"tv",r):"",J=mn,We=`${J}:${u}:${b}:${T}:${j}`,hn=_e(()=>!r||!s||E||Ue||be||K!==We||z[Le]?.type!=="hls"?null:{kind:v?"movie":"tv",...v?{}:{season:u},showId:r,episode:String(v?1:b),provider:T,source:j,mode:"sub",title:s.title},[r,s,E,Ue,be,K,We,z,Le,v,u,b,T,j]),gs=go(m.engine,hn,be||!s),ys=Fo(),Kn=zo(),Ge=Vo(),Xe=Uo(),{toggle:_s,bookmarkedIds:cr,pending:dr}=Wo(),{data:Ss}=Ho(s?mn:void 0),Qt=Ss?!!Ss.inLibrary:mn?cr.has(mn):!1,ur=N(()=>{!s||!r||_s({tmdbId:Number(r),mediaType:I||"tv",title:s.title,poster:s.poster,year:s.year,adult:s.adult})},[s,r,I,_s]),{data:Ze,isFetched:jt,isFetching:Yn}=qo(J||void 0,u,b),pn=_e(()=>Ke.map(e=>e.episode_number).sort((e,n)=>e-n),[Ke]),Gt=pn.indexOf(b),Qn=Gt>0?pn[Gt-1]:null,M=Gt>=0&&Gt<pn.length-1?pn[Gt+1]:null,vn=_e(()=>(s?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[s]),ee=_e(()=>{if(v||M!=null)return null;const e=vn.indexOf(u);return e>=0&&e<vn.length-1?vn[e+1]:(s?.number_of_seasons??0)>u?u+1:null},[v,M,vn,u,s?.number_of_seasons]),jn=Yo(s?.status),ft=v||M==null&&ee==null&&jn,Cs=M==null&&ee==null&&!ft,$e=Ze?.currentTime??0,bn=H(null),[gt,fn]=y(!1),[At,Ts]=y(0),[Xt,ks]=y(!1),[xt,yt]=y(!1),[mr,Gn]=y(!1),[hr,pr]=y(""),[gn,vr]=y(!1),[br,Xn]=y(!1),[Zn,Jn]=y(!1),{isTheaterMode:He,toggleTheaterMode:es,handleLayoutClick:fr}=yo(),Ns=Ze?.duration??0,Es=Ze?.completed===1,Zt=`${J}:${u}:${b}`,[ws,gr]=y(null);C(()=>{jt&&gr(e=>e?.key===Zt?e:{key:Zt,watched:Es||rn($e,Ns)})},[jt,Zt,Es,$e,Ns]);const yr=jt&&ws?.key===Zt&&ws.watched,[yn]=y(Qo),[_r,Is]=y(!1);C(()=>{Is(!1)},[Zt]);const As=!d&&!Ie&&yr&&!Zn,Je=As&&yn,_t=As&&!yn&&!_r,et=xt&&yn,Sr=xt&&!yn,xs=N(()=>{Jn(!0),yt(!1)},[]);C(()=>{const e=n=>{n.defaultPrevented||n.ctrlKey||n.metaKey||n.altKey||n.repeat||n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&es()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[es]),_o(m,(z.length>0||Dt!=="")&&!He&&!gt&&!xt&&!Je&&!_t);const Cr=Xo(),[Pt,Tr]=y(jo),kr=N(e=>{Tr(e),Go(e)},[]),Nr=e=>t("div",{className:e,children:[t("button",{className:`${ne.episodeNavBtn} ${ne.secondary} ${Pt?S.autoplayActive:""}`,onClick:()=>kr(!Pt),type:"button","aria-pressed":Pt,children:Pt?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),t("button",{className:`${ne.episodeNavBtn} ${ne.secondary}`,onClick:()=>Kn.mutate({mediaId:J??"",season:u,episode:b}),disabled:Kn.isPending,type:"button",children:[t(pe,{name:"undo",size:14}),Kn.isPending?"Resetting...":"Reset Progress"]}),t("button",{className:`${ne.episodeNavBtn} ${ne.secondary}`,onClick:()=>Qn!=null&&Ct(String(Qn)),disabled:i||Qn==null,type:"button",children:[t(pe,{name:"chevron-left",size:12}),"Prev EP"]}),t("button",{className:`${ne.episodeNavBtn} ${ne.primary}`,onClick:()=>M!=null&&Ct(String(M)),disabled:i||M==null,type:"button",children:["Next EP",t(pe,{name:"chevron-right",size:12})]}),Cr&&t("button",{className:`${ne.episodeNavBtn} ${ne.episodePickerBtn}`,onClick:()=>Xn(!0),type:"button",children:[t(pe,{name:"list-ul",size:12}),"Episodes"]})]}),tt=H(!1),qe=H(null),ts=H(0),te=H(null),Ps=N(()=>{te.current=$e,Jn(!0),yt(!1)},[$e]),St=H(""),Er=Gs($e),Jt=!d&&!tt.current&&!Zn&&(gt||xt||Er||Je||_t),_n=H(Jt);_n.current=Jt;const Sn=H(!1);C(()=>{Sn.current=Xt},[Xt]);const nt=N((e,n)=>{if(!J||!n||n<30)return;const a=rn(e,n);Math.abs(e-ts.current)<10&&!a||(ts.current=e,ys.mutate({mediaId:J,season:u,episode:b,currentTime:Math.floor(e),duration:Math.floor(n),completed:a,title:s?.title??null,poster:s?.poster??null,backdrop:s?.backdrop??null,year:s?.year??null,overview:s?.overview??null,tmdbId:s?.id??null,mediaType:I||"tv",adult:s?.adult?1:0}))},[J,u,b,ys,s,I]),Be=N((e,n)=>{Fn();const a=new URLSearchParams(f);a.set("type",f.get("type")||"tv"),a.set("s",String(e)),a.set("e",String(n)),L(`${window.location.pathname}?${a.toString()}`)},[f,L,Fn]),en=N(()=>{const e=h.current;if(!e||v||M==null){Gn(!1);return}const n=e.duration||0,a=e.currentTime||0;Gn(n>0&&a/n>=.8)},[v,M,h]),Cn=N((e,n)=>["tv-sources",T,v?"movie":"tv",r,e,n,j],[T,v,r,j]),Tn=N(async(e,n)=>{if(!s||!r||!T)return{valid:!1,sources:[]};const a=v?"movie":"tv",l=await ot.tv.sources.query({provider:T,type:a,tmdbId:String(r),season:e,episode:n,title:s.title||"",year:s.year||"",totalSeasons:String(s.number_of_seasons||1),imdbId:s.imdb_id||"",...j?{server:j}:{}});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,server:"server"in l?l.server:void 0,embedUrl:"embedUrl"in l?l.embedUrl:void 0}},[s,r,T,v,j]),Ms=N(()=>{if(v||!s||!r||!T||E||M==null)return;const e=Cn(u,M);R.getQueryState(e)?.status!=="success"&&R.prefetchQuery({queryKey:e,queryFn:()=>Tn(u,M),staleTime:300*1e3,gcTime:1800*1e3})},[v,s,r,T,E,M,u,R,Cn,Tn]),wr=N(()=>{if(Ie)return;en();const e=h.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&Ms(),!qe.current&&(qe.current=setTimeout(()=>{qe.current=null,nt(e.currentTime,e.duration||0)},5e3)))},[nt,h,Ie,en,Ms]),Ir=N(()=>{const e=h.current;if(!(!e||!s)&&(qe.current&&clearTimeout(qe.current),qe.current=null,nt(e.currentTime,e.duration||0),!i)){if(M!=null){Pt&&(ve(M),Be(u,M));return}!v&&ee==null&&!jn||(pr(v?s.title:`${s.title} - Season ${u}`),yt(!0),tt.current=!0)}},[v,s,u,M,ee,jn,Pt,nt,Be,h,i]),{checkEnd:kn,logDuration:Ls}=So({videoRef:h,sourceType:E?"iframe":void 0,resetKey:`${J}:${u}:${b}:${Zn}`,onEnd:Ir}),Ar=N(()=>{m.actions.onPlay()},[m.actions]),xr=N(()=>{m.actions.onPause();const e=h.current;e&&!e.ended&&nt(e.currentTime,e.duration||0)},[m.actions,nt,h]),Pr=N(()=>{const e=h.current;if(e){try{const n=parseFloat(F.getItem("playerVolume")||"");isNaN(n)||(e.volume=Math.max(0,Math.min(1,n))),e.muted=F.getItem("playerMuted")==="true"}catch{}if(te.current!=null&&te.current>0){try{e.currentTime=te.current}catch{}te.current=null}en()}},[h,en]),ns=N(()=>{const e=h.current;if(e&&te.current!=null&&te.current>0){try{e.currentTime=te.current}catch{}te.current=null}},[h]),Mr=N(()=>{At>0&&(te.current=At);const e=h.current;if(e&&At>0){try{e.currentTime=At,te.current=null}catch{}e.play().catch(()=>{})}fn(!1),tt.current=!0},[At,h]),Rs=N(()=>{te.current=null;const e=h.current;e&&(e.currentTime=0,e.play().catch(()=>{})),fn(!1),tt.current=!0},[h]),$s=N(()=>{M!=null&&(tt.current=!0,ve(M),Be(u,M))},[M,u,Be]),ss=N(()=>{ee!=null&&(yt(!1),tt.current=!0,Fe(ee),ve(1),Be(ee,1))},[ee,Be]),rs=N(async()=>{if(J)try{Qt?await Ge.mutateAsync({id:J,status:"Completed"}):s&&r&&(await Xe.mutateAsync({tmdbId:Number(r),mediaType:I||"tv",title:s.title,poster:s.poster,backdrop:s.backdrop,year:s.year,overview:s.overview,adult:s.adult,status:"Completed",silent:!0}),Qs.success("Moved to Completed")),yt(!1),L("/")}catch{}},[J,Qt,Ge,Xe,s,r,I,L]);C(()=>{tt.current=!1,bn.current=null,fn(!1),Gn(!1),Ts(0),ks(!1),Jn(!1),Sn.current=!1,te.current=null,ts.current=0},[J,u,b]),C(()=>{St.current=We},[We]),C(()=>{jt&&(ks(!0),Sn.current=!0)},[jt,J,u,b]),C(()=>{if(d||Yn||!Ze||tt.current)return;const e=`${J}:${u}:${b}`;if(bn.current===e)return;bn.current=e;const n=Ze,a=n.currentTime??0;Gs(a)&&n.completed!==1&&!rn(a,n.duration??0)&&(Ts(a),fn(!0))},[Ze,Yn,J,u,b,d]),C(()=>{!d&&gt&&h.current&&h.current.pause()},[gt,h,d]),C(()=>{!d&&_t&&h.current&&h.current.pause()},[_t,h,d]),C(()=>{(Je||_t||et)&&m.state.isFullscreen&&m.actions.toggleFullscreen()},[Je,_t,et,m.state.isFullscreen,m.actions]),C(()=>{const e=h.current;return()=>{qe.current&&clearTimeout(qe.current),qe.current=null,!e?.ended&&m.engine.getState().duration>0&&nt(m.engine.getTimeline().currentTime,m.engine.getState().duration)}},[m.engine,nt,h]);const os=N(e=>{let n=null,a=!0;try{n=F.getItem("tvLastSubtitle"),a=F.getItem("tvSubtitlesEnabled")!=="false"}catch{}return vs(e,{lastKey:n,enabled:a})},[]),tn=N((e,n)=>{if(!(e<0))try{F.setItem("tvSubtitlesEnabled","true"),F.setItem("tvSelectedSubtitle",String(e));const a=n?.[e];a&&F.setItem("tvLastSubtitle",xn(a))}catch{}},[]),Bs=N(e=>{if(e.length===0)return 0;let n=null;try{n=F.getItem("tvLastAudio")}catch{}if(n){const a=e.findIndex(k=>xn(k)===n);if(a>=0)return a;const l=n.indexOf("|||"),c=l>=0?n.slice(0,l):n,g=l>=0?n.slice(l+3):n,A=e.findIndex(k=>k.language===c||k.label===g);if(A>=0)return A}return vs(e,{lastKey:null,enabled:!0})},[]),Os=N(e=>{let n=null;try{n=F.getItem("tvLastQuality")}catch{}if(!n||e.length===0)return 0;const a=e.findIndex(k=>(k.quality||"")===n);if(a>=0)return a;const l=k=>{const q=/(\d{3,4})/.exec(k||"");return q?parseInt(q[1],10):0},c=l(n);if(!c)return 0;let g=0,A=1/0;return e.forEach((k,q)=>{const _=l(k.quality),O=Math.abs(_-c);_>0&&O<A&&(A=O,g=q)}),g},[]),{data:Ds}=Ko(J||void 0),Fs=_e(()=>(Ds?.progress??[]).filter(n=>n.season===u&&(n.completed===1||rn(n.currentTime,n.duration))).map(n=>String(n.episode)),[Ds,u]),zs=_e(()=>Ke.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})),[Ke]),Vs=_e(()=>(s?.genres??[]).map(e=>e.name).slice(0,5),[s]),Us=_e(()=>{const e=le??s?.next_episode_to_air??null;if(!e||!e.air_date)return null;const n=new Date(`${e.air_date}T00:00:00`);if(isNaN(n.getTime()))return null;const a=n.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),l=`Next episode: S${e.season_number} E${e.episode_number} · ${a}`,c=e.air_timestamp;if(typeof c!="number"||c<=0)return l;let g=Math.floor((c-Pe)/1e3);if(g<=0)return null;const A=Math.floor(g/86400);g%=86400;const k=Math.floor(g/3600);g%=3600;const q=Math.floor(g/60),_=g%60,O=`${A}d ${k}h ${String(q).padStart(2,"0")}m ${String(_).padStart(2,"0")}s`;return`${l} · in ${O}`},[le,s,Pe]),as=_e(()=>[s?.year,s?.status,s?.number_of_seasons?`${s.number_of_seasons} Season${s.number_of_seasons>1?"s":""}`:null,s?.number_of_episodes?`${s.number_of_episodes} Episodes`:null,Us].filter(Boolean),[s,Us]);C(()=>{if(!i&&ue.length!==0&&!ue.some(e=>e.id===T)){const e=ue.find(n=>n.tier==="direct")?.id??ue[0].id;Ye(e);try{F.setItem("tvProvider",e)}catch{}}},[ue,T,i]),C(()=>{ae([]),zt(""),Ut(""),bt(!1)},[T]),C(()=>{if(!i&&me.length!==0&&!me.includes(j)){Ft(me[0]);try{F.setItem("tvServer",me[0])}catch{}}},[me,j,i]),C(()=>{if(!r){$(null),oe([]),ct(""),p(""),vt("");return}const e=Number(r),n=I||"tv";$(null),oe([]),ct(""),p(""),vt("");const a=parseInt(U.current.get("s")||"",10),l=parseInt(U.current.get("e")||"",10);Fe(isNaN(a)?1:a),ve(isNaN(l)?1:l),Qe(0),ot.tv.details.query({type:n,id:String(e)}).then(c=>{const g={id:c.id,title:c.title||"",overview:c.overview||"",vote_average:c.vote_average,year:c.year,poster:c.poster,backdrop:c.backdrop,imdb_id:c.imdb_id||void 0,adult:c.adult,status:c.status,in_production:c.in_production,seasons:c.seasons,number_of_seasons:c.number_of_seasons,number_of_episodes:c.number_of_episodes,first_air_date:c.first_air_date,last_air_date:c.last_air_date,next_episode_to_air:c.next_episode_to_air,last_episode_to_air:c.last_episode_to_air};if($(g),ce(null),g.seasons&&g.seasons.length>0&&isNaN(a)){const A=g.seasons.find(k=>k.season_number===1)?.season_number??g.seasons[0].season_number;Fe(A)}}).catch(()=>{})},[r,I]),C(()=>{if(!s||!r)return;if(!(s.seasons!==void 0||s.number_of_seasons!==void 0)){it([]);return}const n=parseInt(f.get("e")||"",10);ce(null),ot.tv.episodes.query({id:String(r),season:String(u)}).then(a=>{const l=(a.episodes||[]).map(c=>({episode_number:c.episode_number,name:c.name||"",vote_average:c.vote_average,overview:c.overview||"",still_path:c.still_path||""}));it(l),ce(a.nextAiring??null),l.length!==0&&ve(c=>!isNaN(n)&&l.some(g=>g.episode_number===n)?n:l.some(g=>g.episode_number===c)?c:l[0].episode_number)}).catch(()=>{})},[s,r,u,f]),C(()=>{if(!E||!s||!r)return;hs(`/api/tv/embed/${T}/${v?"movie":"tv"}/${r}?season=${u}&episode=${b}`).then(n=>{if(n.url)return vt(n.url),hs(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(a=>{a.finalUrl&&vt(a.finalUrl)})}).catch(()=>{})},[T,s,r,u,b,v,E]);const Nn=N(async()=>{if(!s||!r||!T||E||s.adult&&!Yt)return;const e=We;Te(!0),p(""),B.current.length===0&&(oe([]),Qe(0),ut([]),mt([]));try{const n=await R.fetchQuery({queryKey:Cn(u,b),queryFn:()=>Tn(u,b),staleTime:3e5,gcTime:18e5});if(St.current!==e)return;if(Te(!1),!n.valid||!n.sources?.length){p(n.error?`${n.error}`:me.length>0?`No streams from ${j}. Try another server.`:"No streams available.");return}if(d&&j&&n.server&&n.server!==j){oe([]),p("The host's selected server is unavailable. Automatic source switching is disabled in watch-along rooms.");return}!i&&!j&&n.server&&Ft(n.server);const a=d?n.sources.filter(k=>k.type==="hls"):n.sources;if(d&&a.length===0){oe([]),p("The room requires a direct HLS source. No compatible stream is available here.");return}oe(a),Lt(n.server||j),ct(e),n.servers?.length&&ae(n.servers),n.embedUrl&&zt(n.embedUrl),Qe(Os(a)),n.referer&&ln(n.referer);const l=n.audioTracks||[];ut(l),wt(l.length>0?Bs(l):0);const c=(n.subtitles||[]).map(k=>({...k,source:"provider"}));if(mt(c),c.length>0){const k=os(c);fe(k),k>=0&&tn(k,c)}else fe(-1);const g=v?"movie":"tv",A=r;ot.tv.subtitles.query({type:g,tmdbId:String(A),season:String(u),episode:String(b)}).then(k=>{if(St.current!==e)return;const q=(Array.isArray(k.subtitles)?k.subtitles:[]).map(_=>({..._,source:"provider"}));q.length!==0&&mt(_=>{const O=[..._,...q.filter(X=>!_.some(W=>W.url===X.url))];return _.length===0&&O.length>0&&Promise.resolve().then(()=>{if(St.current!==e)return;const X=os(O);X>=0&&(fe(X),tn(X,O))}),O})}).catch(()=>{}),p("")}catch(n){if(St.current!==e)return;Te(!1),p(n instanceof Error?n.message:"Failed to load streams.")}},[s,r,T,u,b,v,E,Yt,me,j,os,tn,Bs,Os,R,Cn,Tn,We,d,i]),is=N(()=>{const e=h.current;e&&!isNaN(e.currentTime)&&(te.current=e.currentTime)},[h]),Lr=N(e=>{if(!(i||d&&e==="Embed")){if(e==="Embed"){bt(!0);return}is(),bt(!1),Ft(e);try{F.setItem("tvServer",e)}catch{}p("")}},[is,i,d]),Rr=N(e=>{Ye(e);try{F.setItem("tvProvider",e)}catch{}},[]);C(()=>{T&&s&&!E&&Nn()},[T,s,Nn,E]),C(()=>{if(Je){m.engine.unload();return}if(!h.current)return;if(ge.current=null,E||Ue||d&&z[Le]?.type!=="hls"){m.engine.unload();return}if(Ie&&!d)return m.engine.loadSource({url:"/av-sync-test.mp4"},{autoPlay:!_n.current});if(un.current!=null&&(te.current=un.current,un.current=null),K===We&&te.current==null&&!_n.current)try{const _=h.current;_&&!_.ended&&_.currentTime>1&&(te.current=_.currentTime)}catch{}const n=te.current??0,a=!be&&K===We?Ue?"":z[Le]?.url||"":"";if(!a){try{h.current?.pause(),h.current?.removeAttribute("src"),h.current?.load()}catch{}return}const l=h.current;l.pause(),l.removeAttribute("src"),l.load(),m.actions.resetMediaState();const c=`/api/tv/stream-proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(pt)}&provider=${encodeURIComponent(T)}`,g=Ka()||document.body.classList.contains("low-end"),A=g?60:180,k=m.engine.loadSource({url:c,hls:z[Le]?.type==="hls"},{hlsConfig:{enableWorker:!0,lowLatencyMode:!1,startPosition:n>0?n:-1,maxBufferLength:A,maxMaxBufferLength:A+(g?30:60),backBufferLength:g?30:60,maxBufferSize:(g?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}}}},onHls:(_,O)=>{ge.current=_;const X=()=>{let V=!1,D=0;try{V=F.getItem("tvSubtitlesEnabled")==="true";const x=parseInt(F.getItem("tvSelectedSubtitle")||"0",10);!isNaN(x)&&x>=0&&(D=x)}catch{}return{enabled:V,index:D}},W=()=>{if(typeof _.subtitleTrack!="number")return;if(Z.current.length>0){_.subtitleTrack=-1;return}const V=Array.isArray(_.subtitleTracks)?_.subtitleTracks:[];if(V.length===0){_.subtitleTrack=-1;return}const D=X();if(D.enabled){const x=D.index<V.length?D.index:0;_.subtitleTrack=x,fe(x),qn()}else _.subtitleTrack=-1};Ha(_,O.Events,{getWant:()=>re.current,onResolve:V=>wt(V)}),_.on(O.Events.MANIFEST_PARSED,W),_.on(O.Events.SUBTITLE_TRACKS_UPDATED,()=>{W()}),_.on(O.Events.SUBTITLE_TRACK_SWITCH,(V,D)=>{if(Z.current.length>0){if(D.id!==-1)try{_.subtitleTrack=-1}catch{}return}const x=Array.isArray(_.subtitleTracks)?_.subtitleTracks:[];if(x.length!==0){if(D.id===-1){const Ae=X();if(Ae.enabled){const he=Ae.index<x.length?Ae.index:0;_.subtitleTrack=he;return}}fe(D.id),qn()}})},onReady:()=>{(n>0||!_n.current&&Sn.current)&&m.engine.play()},onError:_=>{p(_.message),Te(!1),ge.current=null}}),q=()=>{const X=l.error?.code===4?"Video source not supported or not found":"Failed to load video stream";p(`${X}. The source may be invalid or expired. Try switching source or reloading.`),Te(!1)};return l.addEventListener("error",q),()=>{k(),ge.current=null,l.removeEventListener("error",q)}},[z,K,be,Le,T,pt,E,Ue,h,un,Ie,J,u,b,ns,qn,m.actions,m.engine,We,d,Je]),C(()=>{if(i||!Xt||gt||xt||Jt||E||Ie)return;const e=h.current;!e||!e.paused||e.ended||e.readyState<1||(ns(),m.engine.play())},[Xt,gt,xt,Jt,E,Ie,ns,h,i,m.engine]),C(()=>{const e=ge.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=Ve)},[Ve]),C(()=>{const e=ge.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||Z.current.length>0||(se>=0?e.subtitleTrack=se:e.subtitleTrack=-1)},[se]),C(()=>{const e=h.current;if(!(!e||E)&&(e.querySelectorAll("track").forEach(n=>n.remove()),Z.current=[],Ee.length!==0&&(Ee.forEach(n=>{const a=document.createElement("track");a.kind="subtitles",a.label=n.label||n.language||"Unknown",a.srclang=n.language||n.label||"en";const l=n.source==="opensub",c=l?"":pt,g=l?"&scrape=1":"",A=n.encoding?`&enc=${encodeURIComponent(n.encoding)}`:"",k=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(c)}${g}${A}`;a.src=k,a.addEventListener("load",()=>{const q=Z.current.indexOf(a),_=a.track;if(_&&q>=0){const O=q===ie.current;_.mode=O&&!Hn.current?"showing":"hidden"}}),e.appendChild(a),Z.current.push(a)}),Ee.length>0)))try{const n=ge.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[Ee,pt,E,T,j,h]),C(()=>{const e=h.current;if(!e||E)return;const n=ge.current;Z.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const a=()=>{const g=bs(m.state.subtitleFontSize,e.clientHeight||720),A=Math.max(0,Math.min(100,100-m.state.subtitlePosition)),k=()=>{const W=g*16,V=e.videoHeight||e.clientHeight||720,D=e.videoWidth||e.clientWidth||1280;return{step:W*1.3/V*100,chars:Math.max(20,Math.floor(D/(W*.55)))}},q=(W,V)=>{const D=W;D.snapToLines=!1,D.line=V},_=W=>{if(!W.cues)return;Array.from(W.cues).forEach(he=>q(he,A));const V=Array.from(W.activeCues??[]);if(V.length<=1){V.forEach(he=>q(he,A));return}const{step:D,chars:x}=k();let Ae=A;for(let he=V.length-1;he>=0;he--){const st=String(V[he].text??"").replace(/<[^>]*>/g,"").split(`
3
+ `).reduce((wn,nn)=>wn+Math.max(1,Math.ceil(nn.length/x)),0);Ae=Math.max(0,Ae-st*D),q(V[he],Ae),Ae-=D*.4}},O=Z.current;if(O.length>0){O.forEach((W,V)=>{const D=W.track;if(!D)return;const x=V===se;D.mode=x&&!Ne?"showing":"hidden",x&&!Ne&&_(D)});return}const X=Array.from(e.textTracks);X.length!==0&&X.forEach((W,V)=>{const D=V===se;W.mode=D&&!Ne?"showing":"hidden",D&&!Ne&&_(W)})};a();const l=()=>a();e.textTracks.addEventListener("addtrack",l),e.addEventListener("loadedmetadata",a,{once:!0});const c=window.setTimeout(a,600);return()=>{e.textTracks.removeEventListener("addtrack",l),e.removeEventListener("loadedmetadata",a),window.clearTimeout(c)}},[se,Ee,E,T,h,Ne,m.state.subtitleFontSize,m.state.subtitlePosition]),C(()=>{if(!Ne)return;const e=h.current,n=dn.current;if(!e||!n)return;const a=It/1e3,l=zn/1e3,c=new Set;let g=[],A=-1,k=-1,q=-1,_=-1,O=0,X=0,W=!1;const V=()=>{const Q=ie.current;if(Q<0)return null;const rt=Z.current;return rt.length>0?rt[Q]?.track??null:Array.from(e.textTracks)[Q]??null},D=(Q,rt)=>{const ye=Q.cues;if(!ye||ye.length===0)return Array.from(Q.activeCues??[]);let Tt=0,kt=ye.length;for(;Tt<kt;){const Oe=Tt+kt>>>1;ye[Oe].endTime+a<rt?Tt=Oe+1:kt=Oe}const sn=[];for(let Oe=Tt;Oe<ye.length;Oe++){const In=ye[Oe];if(In.startTime+a>rt)break;In.endTime+a>=rt&&sn.push(In)}return sn},x=()=>{const Q=V(),rt=e.currentTime-l,ye=Q?D(Q,rt):[],Tt=e.clientWidth,kt=e.clientHeight,sn=e.videoWidth,Oe=e.videoHeight;if(ye.length===g.length&&ye.every((ds,us)=>ds===g[us])&&Tt===A&&kt===k&&sn===q&&Oe===_||(g=ye,A=Tt,k=kt,q=sn,_=Oe,n.textContent="",ye.length===0))return;const Ks={font:m.state.subtitleFont,fontSize:bs(m.state.subtitleFontSize,kt),position:m.state.subtitlePosition,bgOpacity:m.state.subtitleBgOpacity,bgColor:m.state.subtitleBgColor,textColor:m.state.subtitleTextColor,edge:m.state.subtitleEdge,outlineWidth:m.state.subtitleOutlineWidth,outlineColor:m.state.subtitleOutlineColor,bold:m.state.subtitleBold},Ur=Co(Ks),Wr=To(e,Ks.position);ye.forEach((ds,us)=>{const Ys=String(ds.text??"");if(!ko(Ys).trim())return;const ms=document.createElement("div"),Hr=(ye.length-1-us)*1.7;ms.style.cssText=`${Ur}
4
+ bottom: calc(${Wr}px + ${Hr}em);`,ms.innerHTML=No(Ys),n.appendChild(ms)})},Ae=()=>{Array.from(e.textTracks).forEach(Q=>{c.has(Q)||(c.add(Q),Q.addEventListener("cuechange",x))})},he=()=>{Ae(),x()},cs=()=>{if(W||X)return;const Q=()=>{X=0,!(W||e.paused||e.ended)&&(x(),cs())};X=window.requestAnimationFrame(Q)},st=e,wn=()=>{O=0,x(),!W&&st.requestVideoFrameCallback&&(O=st.requestVideoFrameCallback(wn))},nn=()=>{x(),st.requestVideoFrameCallback?O||(O=st.requestVideoFrameCallback(wn)):cs()};Ae(),e.textTracks.addEventListener("addtrack",he),e.textTracks.addEventListener("removetrack",he),e.addEventListener("timeupdate",x),e.addEventListener("seeked",x),e.addEventListener("loadedmetadata",x),e.addEventListener("play",nn);const Hs=Array.from(e.querySelectorAll("track"));Hs.forEach(Q=>Q.addEventListener("load",x));const qs=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>x());return qs?.observe(e),x(),nn(),()=>{W=!0,c.forEach(Q=>Q.removeEventListener("cuechange",x)),e.textTracks.removeEventListener("addtrack",he),e.textTracks.removeEventListener("removetrack",he),e.removeEventListener("timeupdate",x),e.removeEventListener("seeked",x),e.removeEventListener("loadedmetadata",x),e.removeEventListener("play",nn),Hs.forEach(Q=>Q.removeEventListener("load",x)),qs?.disconnect(),X&&window.cancelAnimationFrame(X),O&&st.cancelVideoFrameCallback&&st.cancelVideoFrameCallback(O),n.textContent=""}},[Ne,It,se,Ee,zn,h,m.state.subtitleFont,m.state.subtitleFontSize,m.state.subtitlePosition,m.state.subtitleBgOpacity,m.state.subtitleBgColor,m.state.subtitleTextColor,m.state.subtitleEdge,m.state.subtitleOutlineWidth,m.state.subtitleOutlineColor,m.state.subtitleBold]);const ls=()=>{$(null),oe([]),vt(""),L(-1)},$r=N(e=>{i||(Fe(e),ve(1),Be(e,1))},[Be,i]),En=!v&&s?.seasons&&s.seasons.length>1?t("label",{className:S.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{disabled:i,value:u,onChange:e=>$r(parseInt(e.currentTarget.value,10)||1),className:S.select,children:s.seasons.map(e=>t("option",{value:e.season_number,children:[e.season_number===0?"Specials":`Season ${e.season_number}`," (",e.episode_count," ","ep)"]},e.season_number))})]}):null,Ct=N(e=>{if(i)return;const n=parseInt(e,10);if(!isNaN(n)){try{h.current?.pause()}catch{}ve(n),Be(u,n)}Xn(!1)},[u,Be,h,i]);C(()=>{if(v)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(M!=null?Ct(String(M)):Qs.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[v,M,Ct]);const Br=e=>{wt(e);try{const a=Y[e];a&&F.setItem("tvLastAudio",xn(a))}catch{}const n=ge.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},Or=e=>e.startsWith("[Open Subs]")?e:`[Open Subs] ${e}`,Ws=N((e,n)=>{const a={language:e.language||"en",label:Or(e.label||e.language||"Subtitles"),url:e.url,source:"opensub",encoding:e.encoding};mt(l=>{const g=[...l.filter(k=>k.source!=="opensub"),a],A=g.length-1;return St.current===n&&(fe(A),tn(A,g)),g})},[tn]),Dr=N(async()=>{we(null),Bt([]),Ot([]),ht(!0);const e={provider:T,type:v?"movie":"tv",tmdbId:String(r),season:u,episode:b,title:s?.title||"",year:s?.year||"",imdbId:s?.imdb_id||"",totalSeasons:String(s?.number_of_seasons||1)};try{const n=await ot.tv.openSubtitleLanguages.query(e);Bt(n.languages||[]),(n.languages||[]).length||we("No languages found")}catch(n){we(n instanceof Error?n.message:"Failed to load languages")}finally{ht(!1)}},[r,v,T,u,b,s]),Fr=N(async e=>{we(null),Ot([]),ht(!0);const n={provider:T,type:v?"movie":"tv",tmdbId:String(r),season:u,episode:b,lang:e,title:s?.title||"",year:s?.year||"",imdbId:s?.imdb_id||"",totalSeasons:String(s?.number_of_seasons||1)};try{const a=await ot.tv.openSubtitleFiles.query(n);Ot(a.files||[]),(a.files||[]).length||we("No files found")}catch(a){we(a instanceof Error?a.message:"Failed to load files")}finally{ht(!1)}},[r,v,T,u,b,s]),zr=N(e=>{Ws(e,St.current)},[Ws]),Vr=e=>{fe(e);try{if(e===-1)F.setItem("tvSubtitlesEnabled","false");else{F.setItem("tvSubtitlesEnabled","true"),F.setItem("tvSelectedSubtitle",String(e));const c=Ee[e];c&&F.setItem("tvLastSubtitle",xn(c))}}catch{}const n=h.current,a=ge.current;if(a&&typeof a.subtitleTrack=="number"&&Array.isArray(a.subtitleTracks)&&a.subtitleTracks.length>0&&(a.subtitleTrack=Z.current.length>0||e<0?-1:e),!n)return;const l=Z.current;if(l.length>0){l.forEach((c,g)=>{const A=c.track;if(!A)return;const k=g===e;A.mode=k&&!Ne?"showing":"hidden"});return}Array.from(n.textTracks).forEach((c,g)=>{const A=g===e;c.mode=A&&!Ne?"showing":"hidden"})};return C(()=>{if(!s){document.title="TV & Movies - dango";return}document.title=v?`${s.title} - dango`:`${s.title} - Season ${u} Episode ${b} - dango`},[s,v,u,b]),C(()=>{if(!s||v)return;const e=new URLSearchParams(f),n=e.get("s"),a=e.get("e"),l=String(u),c=String(b);n===l&&a===c||(e.set("type",f.get("type")||"tv"),e.set("s",l),e.set("e",c),L(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[s,v,u,b,f,L]),t("div",{className:`${De.playerPageLayout} ${He?De.theaterMode:""} ${v?De.noSidebar:""}`,onClick:fr,children:[He&&t(Eo,{videoRef:h,active:Wn.enabled&&!E&&z.length>0&&!ke&&!(s?.adult&&!Yt),settings:Wn}),!He&&!v&&t("aside",{className:De.episodeSidebar,children:s?t(wo,{episodes:zs,currentEpisode:String(b),watchedEpisodes:Fs,onEpisodeClick:Ct,header:En}):t(Io,{variant:"sidebar"})}),t("div",{className:De.playerMain,children:[s&&t("div",{className:S.playerSection,onContextMenu:e=>e.preventDefault(),style:s.adult&&!Yt?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:E&&Dt&&!d?t("iframe",{src:Dt,className:S.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!E&&Ht&&!d?t("iframe",{src:Ht,className:S.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!E&&(z.length>0||be)?t(xe,{children:[ke&&t(Zs,{error:ke,onRetry:Nn}),t(za,{player:m,title:s.title,episodeLabel:v?void 0:`S${u} E${b}`,server:Nt||G?.label||T,audioTracks:Y,selectedAudioTrack:Ve,onAudioTrackChange:Br,subtitles:Ee,selectedSubtitle:se,onSubtitleChange:Vr,streams:z,resolutionIdx:Le,onResolutionChange:e=>{is(),Qe(e);try{const n=z[e]?.quality;n&&F.setItem("tvLastQuality",n)}catch{}},onBack:ls,videoDelayEnabled:Kt,onVideoDelayToggle:Dn,videoDelayMs:qt,onVideoDelayChange:fs,onCalibrateAvSync:d?void 0:tr,subtitleDelayMs:It,onSubtitleDelayChange:ar,showNextEpisodeButton:!i&&mr,onNextEpisode:M!=null?()=>Ct(String(M)):void 0,isTheaterMode:He,onTheaterModeToggle:es,ambientSettings:Wn,onAmbientChange:ir,hideChrome:Je||et,onOpenSubtitles:Dr,openSubLanguages:Ln,openSubFiles:Rn,openSubLoading:an,openSubError:$n,onOpenSubLangSelect:Fr,onOpenSubFileSelect:zr,children:t(xe,{children:[t(ao,{autoPlay:!d&&Xt&&!Jt,playsInline:!0,disablePictureInPicture:!0,className:`${S.video} ${Un?S.videoHidden:""}`,onTimeUpdate:()=>{Ie||(wr(),kn())},onEnded:()=>{Ie||kn(!0)},onPlay:Ar,onPause:xr,onSeeked:()=>{Ie||(en(),kn())},onLoadedMetadata:()=>{Pr(),Ls(),kn()},onDurationChange:()=>{Ls()},onContextMenu:e=>e.preventDefault(),onError:()=>{p("Video failed to load. Try another server or reload."),Te(!1)}}),t("canvas",{ref:On,className:`${S.delayCanvas} ${Un?S.delayCanvasActive:""}`}),Ne&&t("div",{ref:dn,className:S.subtitleOverlay}),t(Ao,{isOpen:er,ms:qt,onChange:fs,onApply:sr,onClose:nr,testClipActive:Ie,onTestClip:rr}),(Je||et)&&t("div",{className:S.watchedOverlay,children:[t(pe,{name:"check-circle",size:48,style:{color:"var(--accent-lighter)"}}),t("p",{className:S.watchedTitle,children:et||ft?ee!=null?"Season Complete!":v?"Movie Completed!":"Show Completed!":v?"Movie watched":`S${u} E${b} watched`}),t("p",{className:S.watchedSubtext,children:et||ft?ee!=null?`You finished Season ${u}.`:v?"You finished this movie!":"Congratulations! You finished all available episodes.":"Resume where you left off, replay from the beginning, or continue with the next episode."}),t("div",{className:`${S.watchedActions} ${et?S.watchedActionsCentered:""}`,children:[t("div",{children:$e>5&&!et&&t(Se,{variant:Cs?void 0:"secondary",onClick:Ps,children:`Resume ${on($e)}`})}),t("div",{children:M!=null?t(Se,{onClick:$s,children:`Watch EP ${M}`}):ee!=null?t(Se,{onClick:ss,children:`Start Season ${ee}`}):null}),t("div",{children:[t(Se,{variant:"secondary",onClick:xs,children:"Replay"}),ft&&t(Se,{onClick:rs,disabled:Ge.isPending||Xe.isPending,children:Ge.isPending||Xe.isPending?"Saving...":"Move to Completed"})]})]})]})]})})]}):ke&&!E?t(Zs,{error:ke,onRetry:Nn}):null}),t(Jo,{playback:hn?{selection:hn,position:h.current?.currentTime||0,playing:!1,rate:m.engine.getState().playbackRate}:null,onCreate:()=>{Fn(),m.engine.pause()},needsPlayback:gs.needsPlayback,onEnablePlayback:gs.enablePlayback}),d&&!be&&s&&!hn&&t("p",{role:"alert",children:"The host's direct HLS source is unavailable here. Retry or leave the room to use another source."}),!He&&s&&t(xo,{}),!He&&En&&t("div",{className:S.mobileSeasonRow,children:En}),!He&&s&&t("div",{className:ne.streamPanel,children:[t("div",{className:S.providerRow,children:[t("label",{className:S.controlLabel,children:["Provider",t("select",{value:T,onChange:e=>Rr(e.currentTarget.value),className:S.select,disabled:i||ue.length===0,children:$t?t("option",{value:"",children:"Loading..."}):ue.length===0?t("option",{value:"",children:"No providers available"}):t(xe,{children:[dt.length>0&&t("optgroup",{label:"Direct HLS",children:dt.map(e=>t("option",{value:e.id,children:e.label},e.id))}),ze.length>0&&t("optgroup",{label:"Embeds",children:ze.map(e=>t("option",{value:e.id,children:e.label},e.id))})]})})]}),!v&&Nr(S.providerActions)]}),!i&&!E&&(be?t("div",{className:S.sourceLoader,children:t("div",{className:S.ringSpinner})}):t(Ua,{servers:cn,selectedServer:Wt?"Embed":j,onServerSelect:Lr}))]}),!He&&s&&t("div",{className:De.playerInfoContainer,children:[t("div",{className:De.playerInfoHeader,children:[t("div",{className:De.playerAnimeCard,children:s.poster&&t(eo,{src:`https://image.tmdb.org/t/p/w342${s.poster}`,alt:s.title,loading:"lazy",decoding:"async"})}),t("div",{className:De.videoTitleSection,children:[t("div",{className:ne.titleContainer,children:[t("h1",{children:s.title}),t("div",{className:S.meta,children:[t("span",{className:S.year,children:s.year}),s.vote_average!=null&&s.vote_average>0&&t("span",{className:S.rating,children:[t(pe,{name:"star",size:12}),Number(s.vote_average).toFixed(1)]}),t("span",{className:`${S.typeBadge} ${S[v?"movie":"tv"]}`,children:v?"Movie":"TV Show"})]}),Vs.length>0&&t("div",{className:S.genreRow,children:Vs.map(e=>t("span",{className:S.genreChip,children:e},e))}),as.length>0&&t("div",{className:S.metaRow,children:as.map((e,n)=>t("span",{children:[e,n<as.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:ne.controls,children:t("button",{className:`${ne.watchlistBtn} ${Qt?ne.inList:""}`,onClick:ur,disabled:dr,type:"button",children:[Qt?t(pe,{name:"check",size:14}):t(pe,{name:"plus",size:14}),Qt?"In Watchlist":"Add to Watchlist"]})})]})]}),t("div",{className:De.infoColumns,children:[t("div",{className:`${ne.descriptionSection} ${ne.synopsisFlat}`,children:[t("h3",{children:"Synopsis"}),t(Zo,{text:s.overview,emptyText:"No description available."}),t("button",{className:ne.detailsToggleBtn,onClick:()=>vr(!gn),type:"button",children:[gn?t(pe,{name:"chevron-up"}):t(pe,{name:"chevron-down"}),gn?"Hide Details":"Show Details"]})]}),gn&&t("div",{className:S.detailGrid,children:[s.first_air_date&&t("div",{className:S.detailItem,children:[t("strong",{children:v?"Release Date":"First Air Date"}),t("span",{children:s.first_air_date})]}),s.last_air_date&&t("div",{className:S.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:s.last_air_date})]}),s.networks&&s.networks.length>0&&t("div",{className:S.detailItem,children:[t("strong",{children:"Networks"}),t("span",{children:s.networks.map(e=>e.name).join(", ")})]}),s.created_by&&s.created_by.length>0&&t("div",{className:S.detailItem,children:[t("strong",{children:"Created By"}),t("span",{children:s.created_by.map(e=>e.name).join(", ")})]}),s.episode_run_time&&s.episode_run_time.length>0&&t("div",{className:S.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[s.episode_run_time[0]," min"]})]}),s.imdb_id&&t("div",{className:S.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${s.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:S.imdbLink,children:"View on IMDb"})]})]})]})]}),!v&&t(Po,{isOpen:br,onClose:()=>Xn(!1),episodes:zs,currentEpisode:String(b),watchedEpisodes:Fs,onEpisodeClick:Ct,header:En}),s?.adult&&!Yt&&t(Do,{isOpen:!0,onClose:ls,onGrant:lr}),t(Mo,{isOpen:!d&&gt&&!Yn&&bn.current===`${J}:${u}:${b}`&&Ze?.completed!==1&&!rn($e,Ze?.duration??0),onClose:Rs,title:"Resume Watching",message:t(xe,{children:["You were at ",t("strong",{children:on(At)})]}),restartLabel:"Start from Beginning",onResume:Mr,onRestart:Rs}),t(js,{isOpen:_t,onClose:()=>Is(!0),title:ft?v?"Movie Completed!":"Show Completed!":"Episode Completed",heading:v?s?.title??"Movie":`S${u} E${b}`,message:ft?v?"You finished this movie!":"Congratulations! You finished all available episodes.":v?"You've already watched this movie. Resume where you left off or replay it.":"You've already watched this episode. Resume where you left off, replay it, or continue with the next episode.",children:[$e>5&&t(Se,{variant:Cs?void 0:"secondary",onClick:Ps,children:`Resume ${on($e)}`}),t(Se,{variant:"secondary",onClick:xs,children:"Replay"}),M!=null?t(Se,{onClick:$s,children:["Watch EP ",M]}):ee!=null?t(Se,{onClick:ss,children:["Start Season ",ee]}):ft?t(Se,{onClick:rs,disabled:Ge.isPending||Xe.isPending,children:Ge.isPending||Xe.isPending?"Saving...":"Move to Completed"}):null]}),t(js,{isOpen:Sr,onClose:()=>yt(!1),title:v?"Movie Completed!":ee!=null?"Season Complete!":"Show Completed!",heading:hr,message:v?"You finished this movie!":ee!=null?`You finished Season ${u}.`:"Congratulations! You finished all available episodes.",children:ee!=null?t(Se,{onClick:ss,children:["Start Season ",ee]}):t(xe,{children:[t(Se,{onClick:()=>{yt(!1),ls()},children:"Back to Details"}),t(Se,{onClick:rs,disabled:Ge.isPending||Xe.isPending,children:Ge.isPending||Xe.isPending?"Saving...":"Move to Completed"})]})}),!s&&t("div",{className:S.statusMsg,children:[t(pe,{name:"spinner",className:S.spinner})," Loading..."]})]})]})};export{ji as default};
@@ -1 +1 @@
1
- import{o as F,a as R,p as q,d as c,h as C,T,u as e,g as E}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-C1Pj_eSX.js";import{ah as j,g as U,ai as H,t as J,B as w,F as K,j as I}from"./index-BOJFs4B4.js";import{c as Q,d as X}from"./useTvLibrary-F0S6WnwD.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-1xwHWgGv.js";const Y="_container_198yg_1",Z="_heroSection_198yg_11",ee="_bannerContainer_198yg_17",ne="_banner_198yg_17",te="_bannerOverlay_198yg_37",se="_heroContent_198yg_49",ae="_posterContainer_198yg_62",oe="_poster_198yg_62",ie="_infoGlass_198yg_86",re="_title_198yg_100",le="_quickMeta_198yg_110",ce="_metaItem_198yg_118",de="_iconStar_198yg_126",_e="_iconTv_198yg_130",me="_iconType_198yg_134",he="_genres_198yg_139",ge="_genre_198yg_139",ve="_metaRow_198yg_156",pe="_metaValue_198yg_164",ue="_metaDivider_198yg_168",ye="_synopsisSection_198yg_173",ke="_sectionTitleSmall_198yg_179",be="_synopsis_198yg_173",Ne="_actions_198yg_196",Se="_watchBtn_198yg_202",fe="_watchlistBtn_198yg_226",Ce="_active_198yg_250",Te="_seasonPickerLabel_198yg_256",we="_seasonSelect_198yg_267",Ie="_detailsToggleBtn_198yg_286",Be="_expandedContent_198yg_304",De="_detailGrid_198yg_309",Me="_detailItem_198yg_315",Le="_imdbLink_198yg_333",Pe="_heroSkeleton_198yg_343",$e="_skeletonBanner_198yg_347",Ge="_skeletonContent_198yg_354",xe="_skeletonPoster_198yg_365",Oe="_skeletonInfo_198yg_373",Ae="_skeletonTitle_198yg_380",Ve="_skeletonMeta_198yg_388",We="_skeletonDesc_198yg_396",ze="_skeletonActions_198yg_404",Fe="_errorState_198yg_413",Re="_matureOverlay_198yg_434",qe="_matureContent_198yg_444",n={container:Y,heroSection:Z,bannerContainer:ee,banner:ne,bannerOverlay:te,heroContent:se,posterContainer:ae,poster:oe,infoGlass:ie,title:re,quickMeta:le,metaItem:ce,iconStar:de,iconTv:_e,iconType:me,genres:he,genre:ge,metaRow:ve,metaValue:pe,metaDivider:ue,synopsisSection:ye,sectionTitleSmall:ke,synopsis:be,actions:Ne,watchBtn:Se,watchlistBtn:fe,active:Ce,seasonPickerLabel:Te,seasonSelect:we,detailsToggleBtn:Ie,expandedContent:Be,detailGrid:De,detailItem:Me,imdbLink:Le,heroSkeleton:Pe,skeletonBanner:$e,skeletonContent:Ge,skeletonPoster:xe,skeletonInfo:Oe,skeletonTitle:Ae,skeletonMeta:Ve,skeletonDesc:We,skeletonActions:ze,errorState:Fe,matureOverlay:Re,matureContent:qe};function Qe(){const{id:o}=F(),d=R(),[B]=q(),i=j(B.get("type")),{hasConsent:D}=U(),[t,M]=c(null),[L,m]=c(!0),[u,y]=c(""),[_,P]=c(!1),[h,$]=c(1),G=H(i,o??""),x=Number(o),{data:O}=Q(t?G:void 0),g=!!O?.inLibrary,{toggle:A}=X();C(()=>{o&&(m(!0),y(""),J.tv.details.query({type:i,id:String(o)}).then(s=>{const r={id:s.id,title:s.title||"",overview:s.overview||"",vote_average:s.vote_average,year:s.year,poster:s.poster,backdrop:s.backdrop,imdb_id:s.imdb_id||void 0,adult:s.adult,seasons:s.seasons?.map(z=>({...z,name:""})),number_of_seasons:s.number_of_seasons,number_of_episodes:s.number_of_episodes,status:s.status,first_air_date:s.first_air_date,last_air_date:s.last_air_date};M(r),m(!1)}).catch(s=>{y(s.message),m(!1)}))},[o,i]),C(()=>{document.title=t?.title?`${t.title} - dango`:"TV & Movies - dango"},[t?.title]);const V=()=>{!o||!t||d(l?I(i,o):I(i,o,h,1))},W=()=>{t&&A({tmdbId:x,mediaType:i,title:t.title,poster:t.poster,year:t.year,adult:t.adult})},l=i==="movie",v=!l,k=t?.backdrop?`https://image.tmdb.org/t/p/w1280${t.backdrop}`:"",b=t?.poster?`https://image.tmdb.org/t/p/w500${t.poster}`:"",N=T(()=>t?.genres?t.genres.map(s=>s.name).slice(0,5):[],[t?.genres]),S=T(()=>t?.seasons?[...t.seasons].sort((s,r)=>s.season_number-r.season_number):[],[t?.seasons]),p=[t?.year,t?.status,v&&t?.number_of_seasons?`${t.number_of_seasons} Season${t.number_of_seasons>1?"s":""}`:null,v&&t?.number_of_episodes?`${t.number_of_episodes} Episodes`:null].filter(Boolean);if(L)return e("div",{className:n.container,children:e("div",{className:n.heroSkeleton,children:[e("div",{className:n.skeletonBanner}),e("div",{className:n.skeletonContent,children:[e("div",{className:n.skeletonPoster}),e("div",{className:n.skeletonInfo,children:[e("div",{className:n.skeletonTitle}),e("div",{className:n.skeletonMeta}),e("div",{className:n.skeletonDesc}),e("div",{className:n.skeletonActions})]})]})]})});if(u||!t)return e("div",{className:n.container,children:e("div",{className:n.errorState,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Failed to load details"}),e("p",{children:u||"Something went wrong"}),e(w,{onClick:()=>d(-1),children:"Go Back"})]})});const f=t.adult&&!D;return e("div",{className:n.container,style:f?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:[e("div",{className:n.heroSection,children:[e("div",{className:n.bannerContainer,children:[k&&e("div",{className:n.banner,style:{backgroundImage:`url(${k})`}}),e("div",{className:n.bannerOverlay})]}),e("div",{className:n.heroContent,children:[e("div",{className:n.posterContainer,children:b&&e(K,{src:b,alt:t.title,className:n.poster,decoding:"async"})}),e("div",{className:n.infoGlass,children:[e("div",{children:[e("h1",{className:n.title,children:t.title}),e("div",{className:n.quickMeta,children:[t.vote_average!=null&&t.vote_average>0&&e("div",{className:n.metaItem,children:[e(a,{name:"star",className:n.iconStar}),e("span",{children:Number(t.vote_average).toFixed(1)})]}),e("div",{className:n.metaItem,children:[e(a,{name:"tv",className:n.iconTv}),e("span",{children:l?"Movie":"TV Show"})]}),t.vote_count!=null&&e("div",{className:n.metaItem,children:[e(a,{name:"users",className:n.iconType}),e("span",{children:[t.vote_count.toLocaleString()," votes"]})]})]}),N.length>0&&e("div",{className:n.genres,children:N.map(s=>e("span",{className:n.genre,children:s},s))})]}),p.length>0&&e("div",{className:n.metaRow,children:p.map((s,r)=>e(E.Fragment,{children:[e("span",{className:n.metaValue,children:s}),r<p.length-1&&e("span",{className:n.metaDivider,children:"·"})]},r))}),t.overview&&e("div",{className:n.synopsisSection,children:[e("h2",{className:n.sectionTitleSmall,children:"Synopsis"}),e("p",{className:n.synopsis,children:t.overview})]}),e("div",{className:n.actions,children:[e("button",{className:n.watchBtn,onClick:V,children:[e(a,{name:"play",size:14}),l?"Watch Now":`Start S${h}`]}),e("button",{className:`${n.watchlistBtn} ${g?n.active:""}`,onClick:W,children:[g?e(a,{name:"check",size:14}):e(a,{name:"plus",size:14}),g?"In Watchlist":"Add to Watchlist"]})]}),v&&S.length>1&&e("label",{className:n.seasonPickerLabel,children:[e("span",{children:"Season"}),e("select",{value:h,onChange:s=>$(parseInt(s.currentTarget.value,10)||1),className:n.seasonSelect,children:S.map(s=>e("option",{value:s.season_number,children:[s.season_number===0?"Specials":`Season ${s.season_number}`," (",s.episode_count," Episodes)"]},s.season_number))})]}),e("button",{className:n.detailsToggleBtn,onClick:()=>P(!_),children:[_?e(a,{name:"chevron-up"}):e(a,{name:"chevron-down"}),_?"Hide Details":"Show Details"]}),_&&e("div",{className:n.expandedContent,children:e("div",{className:n.detailGrid,children:[t.first_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:l?"Release Date":"First Air Date"}),e("span",{children:t.first_air_date})]}),t.last_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:"Last Air Date"}),e("span",{children:t.last_air_date})]}),t.networks&&t.networks.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Networks"}),e("span",{children:t.networks.map(s=>s.name).join(", ")})]}),t.created_by&&t.created_by.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Created By"}),e("span",{children:t.created_by.map(s=>s.name).join(", ")})]}),t.episode_run_time&&t.episode_run_time.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Episode Runtime"}),e("span",{children:[t.episode_run_time[0]," min"]})]}),t.imdb_id&&e("div",{className:n.detailItem,children:[e("strong",{children:"IMDb"}),e("a",{href:`https://www.imdb.com/title/${t.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:n.imdbLink,children:"View on IMDb"})]})]})})]})]})]}),f&&e("div",{className:n.matureOverlay,children:e("div",{className:n.matureContent,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Content Warning"}),e("p",{children:"This content may contain mature themes."}),e(w,{onClick:()=>d("/"),children:"Go Back"})]})})]})}export{Qe as default};
1
+ import{o as F,a as R,p as q,d as c,h as C,T,u as e,g as E}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-C1Pj_eSX.js";import{ah as j,h as U,ai as H,t as J,B as w,F as K,k as I}from"./index-CqcwUuWG.js";import{c as Q,d as X}from"./useTvLibrary-D9vDuZs7.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-CC9NocI9.js";const Y="_container_198yg_1",Z="_heroSection_198yg_11",ee="_bannerContainer_198yg_17",ne="_banner_198yg_17",te="_bannerOverlay_198yg_37",se="_heroContent_198yg_49",ae="_posterContainer_198yg_62",oe="_poster_198yg_62",ie="_infoGlass_198yg_86",re="_title_198yg_100",le="_quickMeta_198yg_110",ce="_metaItem_198yg_118",de="_iconStar_198yg_126",_e="_iconTv_198yg_130",me="_iconType_198yg_134",he="_genres_198yg_139",ge="_genre_198yg_139",ve="_metaRow_198yg_156",pe="_metaValue_198yg_164",ue="_metaDivider_198yg_168",ye="_synopsisSection_198yg_173",ke="_sectionTitleSmall_198yg_179",be="_synopsis_198yg_173",Ne="_actions_198yg_196",Se="_watchBtn_198yg_202",fe="_watchlistBtn_198yg_226",Ce="_active_198yg_250",Te="_seasonPickerLabel_198yg_256",we="_seasonSelect_198yg_267",Ie="_detailsToggleBtn_198yg_286",Be="_expandedContent_198yg_304",De="_detailGrid_198yg_309",Me="_detailItem_198yg_315",Le="_imdbLink_198yg_333",Pe="_heroSkeleton_198yg_343",$e="_skeletonBanner_198yg_347",Ge="_skeletonContent_198yg_354",xe="_skeletonPoster_198yg_365",Oe="_skeletonInfo_198yg_373",Ae="_skeletonTitle_198yg_380",Ve="_skeletonMeta_198yg_388",We="_skeletonDesc_198yg_396",ze="_skeletonActions_198yg_404",Fe="_errorState_198yg_413",Re="_matureOverlay_198yg_434",qe="_matureContent_198yg_444",n={container:Y,heroSection:Z,bannerContainer:ee,banner:ne,bannerOverlay:te,heroContent:se,posterContainer:ae,poster:oe,infoGlass:ie,title:re,quickMeta:le,metaItem:ce,iconStar:de,iconTv:_e,iconType:me,genres:he,genre:ge,metaRow:ve,metaValue:pe,metaDivider:ue,synopsisSection:ye,sectionTitleSmall:ke,synopsis:be,actions:Ne,watchBtn:Se,watchlistBtn:fe,active:Ce,seasonPickerLabel:Te,seasonSelect:we,detailsToggleBtn:Ie,expandedContent:Be,detailGrid:De,detailItem:Me,imdbLink:Le,heroSkeleton:Pe,skeletonBanner:$e,skeletonContent:Ge,skeletonPoster:xe,skeletonInfo:Oe,skeletonTitle:Ae,skeletonMeta:Ve,skeletonDesc:We,skeletonActions:ze,errorState:Fe,matureOverlay:Re,matureContent:qe};function Qe(){const{id:o}=F(),d=R(),[B]=q(),i=j(B.get("type")),{hasConsent:D}=U(),[t,M]=c(null),[L,m]=c(!0),[u,y]=c(""),[_,P]=c(!1),[h,$]=c(1),G=H(i,o??""),x=Number(o),{data:O}=Q(t?G:void 0),g=!!O?.inLibrary,{toggle:A}=X();C(()=>{o&&(m(!0),y(""),J.tv.details.query({type:i,id:String(o)}).then(s=>{const r={id:s.id,title:s.title||"",overview:s.overview||"",vote_average:s.vote_average,year:s.year,poster:s.poster,backdrop:s.backdrop,imdb_id:s.imdb_id||void 0,adult:s.adult,seasons:s.seasons?.map(z=>({...z,name:""})),number_of_seasons:s.number_of_seasons,number_of_episodes:s.number_of_episodes,status:s.status,first_air_date:s.first_air_date,last_air_date:s.last_air_date};M(r),m(!1)}).catch(s=>{y(s.message),m(!1)}))},[o,i]),C(()=>{document.title=t?.title?`${t.title} - dango`:"TV & Movies - dango"},[t?.title]);const V=()=>{!o||!t||d(l?I(i,o):I(i,o,h,1))},W=()=>{t&&A({tmdbId:x,mediaType:i,title:t.title,poster:t.poster,year:t.year,adult:t.adult})},l=i==="movie",v=!l,k=t?.backdrop?`https://image.tmdb.org/t/p/w1280${t.backdrop}`:"",b=t?.poster?`https://image.tmdb.org/t/p/w500${t.poster}`:"",N=T(()=>t?.genres?t.genres.map(s=>s.name).slice(0,5):[],[t?.genres]),S=T(()=>t?.seasons?[...t.seasons].sort((s,r)=>s.season_number-r.season_number):[],[t?.seasons]),p=[t?.year,t?.status,v&&t?.number_of_seasons?`${t.number_of_seasons} Season${t.number_of_seasons>1?"s":""}`:null,v&&t?.number_of_episodes?`${t.number_of_episodes} Episodes`:null].filter(Boolean);if(L)return e("div",{className:n.container,children:e("div",{className:n.heroSkeleton,children:[e("div",{className:n.skeletonBanner}),e("div",{className:n.skeletonContent,children:[e("div",{className:n.skeletonPoster}),e("div",{className:n.skeletonInfo,children:[e("div",{className:n.skeletonTitle}),e("div",{className:n.skeletonMeta}),e("div",{className:n.skeletonDesc}),e("div",{className:n.skeletonActions})]})]})]})});if(u||!t)return e("div",{className:n.container,children:e("div",{className:n.errorState,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Failed to load details"}),e("p",{children:u||"Something went wrong"}),e(w,{onClick:()=>d(-1),children:"Go Back"})]})});const f=t.adult&&!D;return e("div",{className:n.container,style:f?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:[e("div",{className:n.heroSection,children:[e("div",{className:n.bannerContainer,children:[k&&e("div",{className:n.banner,style:{backgroundImage:`url(${k})`}}),e("div",{className:n.bannerOverlay})]}),e("div",{className:n.heroContent,children:[e("div",{className:n.posterContainer,children:b&&e(K,{src:b,alt:t.title,className:n.poster,decoding:"async"})}),e("div",{className:n.infoGlass,children:[e("div",{children:[e("h1",{className:n.title,children:t.title}),e("div",{className:n.quickMeta,children:[t.vote_average!=null&&t.vote_average>0&&e("div",{className:n.metaItem,children:[e(a,{name:"star",className:n.iconStar}),e("span",{children:Number(t.vote_average).toFixed(1)})]}),e("div",{className:n.metaItem,children:[e(a,{name:"tv",className:n.iconTv}),e("span",{children:l?"Movie":"TV Show"})]}),t.vote_count!=null&&e("div",{className:n.metaItem,children:[e(a,{name:"users",className:n.iconType}),e("span",{children:[t.vote_count.toLocaleString()," votes"]})]})]}),N.length>0&&e("div",{className:n.genres,children:N.map(s=>e("span",{className:n.genre,children:s},s))})]}),p.length>0&&e("div",{className:n.metaRow,children:p.map((s,r)=>e(E.Fragment,{children:[e("span",{className:n.metaValue,children:s}),r<p.length-1&&e("span",{className:n.metaDivider,children:"·"})]},r))}),t.overview&&e("div",{className:n.synopsisSection,children:[e("h2",{className:n.sectionTitleSmall,children:"Synopsis"}),e("p",{className:n.synopsis,children:t.overview})]}),e("div",{className:n.actions,children:[e("button",{className:n.watchBtn,onClick:V,children:[e(a,{name:"play",size:14}),l?"Watch Now":`Start S${h}`]}),e("button",{className:`${n.watchlistBtn} ${g?n.active:""}`,onClick:W,children:[g?e(a,{name:"check",size:14}):e(a,{name:"plus",size:14}),g?"In Watchlist":"Add to Watchlist"]})]}),v&&S.length>1&&e("label",{className:n.seasonPickerLabel,children:[e("span",{children:"Season"}),e("select",{value:h,onChange:s=>$(parseInt(s.currentTarget.value,10)||1),className:n.seasonSelect,children:S.map(s=>e("option",{value:s.season_number,children:[s.season_number===0?"Specials":`Season ${s.season_number}`," (",s.episode_count," Episodes)"]},s.season_number))})]}),e("button",{className:n.detailsToggleBtn,onClick:()=>P(!_),children:[_?e(a,{name:"chevron-up"}):e(a,{name:"chevron-down"}),_?"Hide Details":"Show Details"]}),_&&e("div",{className:n.expandedContent,children:e("div",{className:n.detailGrid,children:[t.first_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:l?"Release Date":"First Air Date"}),e("span",{children:t.first_air_date})]}),t.last_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:"Last Air Date"}),e("span",{children:t.last_air_date})]}),t.networks&&t.networks.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Networks"}),e("span",{children:t.networks.map(s=>s.name).join(", ")})]}),t.created_by&&t.created_by.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Created By"}),e("span",{children:t.created_by.map(s=>s.name).join(", ")})]}),t.episode_run_time&&t.episode_run_time.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Episode Runtime"}),e("span",{children:[t.episode_run_time[0]," min"]})]}),t.imdb_id&&e("div",{className:n.detailItem,children:[e("strong",{children:"IMDb"}),e("a",{href:`https://www.imdb.com/title/${t.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:n.imdbLink,children:"View on IMDb"})]})]})})]})]})]}),f&&e("div",{className:n.matureOverlay,children:e("div",{className:n.matureContent,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Content Warning"}),e("p",{children:"This content may contain mature themes."}),e(w,{onClick:()=>d("/"),children:"Go Back"})]})})]})}export{Qe as default};
@@ -0,0 +1 @@
1
+ import{d as n,h as b,T as k,u as T}from"./vendor-core-DfaOB3Rn.js";import{ai as _,t as m,n as w,k as I,o as P}from"./index-CqcwUuWG.js";import{d as D}from"./useTvLibrary-D9vDuZs7.js";import{a as W}from"./MediaCard-B13pU_sD.js";const S=({item:e,anchorRect:l,onMouseEnter:i,onMouseLeave:c,onRequestClose:p})=>{const[a,u]=n(null),[d,r]=n(!0),{toggle:v,bookmarkedIds:g}=D(),y=_(e.type,e.id),f=g.has(y);b(()=>{let o=!1;return r(!0),m.tv.details.query({type:e.type,id:String(e.id)}).then(s=>{o||(u({overview:s.overview,vote_average:s.vote_average,number_of_seasons:s.number_of_seasons}),r(!1))}).catch(()=>{o||r(!1)}),()=>{o=!0}},[e.id,e.type]);const h=k(()=>a?.genres?a.genres.slice(0,4).map(o=>o.name):[],[a?.genres]),t=[];return a?.vote_average!=null&&a.vote_average>0&&t.push({icon:"star",label:Number(a.vote_average).toFixed(1),accent:!0}),t.push({icon:"tv",label:e.type==="tv"?"TV Show":"Movie"}),e.year&&t.push({label:e.year}),a?.status&&t.push({label:a.status}),T(W,{anchorRect:l,title:e.title,loading:d,meta:t,genres:h,synopsis:P(a?.overview,200),primaryAction:{to:I(e.type,e.id),label:"Watch now",icon:"play"},secondaryAction:{to:w(e.type,e.id),label:"Details",icon:"info-circle"},bookmarked:f,onToggleBookmark:()=>v({tmdbId:e.id,mediaType:e.type,title:e.title,poster:e.image,year:e.year}),onMouseEnter:i,onMouseLeave:c,onRequestClose:p})};export{S as T};
@@ -1 +1 @@
1
- import{h as I,p as ae,A as re,d as o,T as Y,q as M,u as t}from"./vendor-core-DfaOB3Rn.js";import{I as h}from"./vendor-icons-C1Pj_eSX.js";import{P as D}from"./MediaCard-Ce90T0yC.js";import{a as ne,T as se}from"./useTv-SLXsIWFQ.js";import{S as le}from"./SkeletonGrid-zCAxRZIz.js";import{u as ie,T as W,M as Q,a9 as oe,B as x}from"./index-BOJFs4B4.js";import{E as ce}from"./ErrorMessage-hMt90aG4.js";import{s as r}from"./Search.module-DjQZ0jox.js";import"./MediaPopupShell-BewMMT93.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-DoPl5ONK.js";import"./TvPopup-Ci4SXMWf.js";import"./useTvLibrary-F0S6WnwD.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-1xwHWgGv.js";const de=[{value:"multi",label:"All"},{value:"tv",label:"TV Shows"},{value:"movie",label:"Movies"}],ue=[{value:"popularity.desc",label:"Popularity"},{value:"vote_average.desc",label:"Top Rated"},{value:"primary_release_date.desc",label:"Newest"},{value:"primary_release_date.asc",label:"Oldest"},{value:"vote_count.desc",label:"Most Voted"}],O=new Date().getFullYear(),me=[{value:"ALL",label:"All Years"},...Array.from({length:O-1980+1},(l,m)=>({value:String(O-m),label:String(O-m)}))];function Ae(){I(()=>{document.title="Search TV & Movies - dango"},[]);const[l,m]=ae(),{lowEndMode:K}=ie(),C=re(null),[g,H]=o(l.get("q")||""),[p,U]=o(l.get("q")||""),[u,v]=o(parseInt(l.get("page")||"1",10)||1),[i,J]=o(l.get("type")||"multi"),[$,k]=o(l.get("genre")||""),[y,B]=o(l.get("year")||"ALL"),[f,E]=o(l.get("sort_by")||"popularity.desc"),[b,X]=o(!1),[c,N]=o(()=>{const e={},a=l.get("genre")||"";return a&&(e[a]="include"),e}),P=Y(()=>{if(i==="tv")return Object.entries(W).map(([a,n])=>({id:a,name:n}));if(i==="movie")return Object.entries(Q).map(([a,n])=>({id:a,name:n}));const e=new Map;for(const[a,n]of Object.entries(W))e.set(a,n);for(const[a,n]of Object.entries(Q))e.set(a,n);return Array.from(e.entries()).map(([a,n])=>({id:a,name:n}))},[i]),S=Y(()=>Object.entries(c).filter(([,a])=>a==="include").map(([a])=>a).join(","),[c]),{data:L,isLoading:w,isError:Z,error:ee}=ne({query:p,type:i,genre:S,year:y,sort_by:f,page:u}),T=L?.results||[],_=L?.total_pages||0,j=L?.total_results||0,R=u<Math.min(_,500),d=M((e={})=>{const a=new URLSearchParams,n=e.q!==void 0?e.q:p,s=e.type!==void 0?e.type:i,G=e.year!==void 0?e.year:y,V=e.sort!==void 0?e.sort:f,F=e.page!==void 0?e.page:String(u),z=e.genre!==void 0?e.genre:S;n.trim()&&a.set("q",n.trim()),s!=="multi"&&a.set("type",s),z&&a.set("genre",z),G!=="ALL"&&a.set("year",G),V!=="popularity.desc"&&a.set("sort_by",V),F!=="1"&&a.set("page",F),m(a,{replace:!0})},[p,i,y,f,u,S,m]),A=M(()=>{oe(),v(1),U(g),d({q:g,page:"1"}),window.scrollTo({top:0,behavior:"smooth"})},[g,d]),q=M(e=>{if(v(e),d({page:String(e)}),C.current){const a=C.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:a,behavior:"smooth"})}},[d]),te=M(e=>{N(a=>{const n=a[e],s={...a};return n==="include"?s[e]="exclude":n==="exclude"?delete s[e]:s[e]="include",s}),v(1)},[]);return I(()=>{const a=Object.entries(c).filter(([,n])=>n==="include").map(([n])=>n).join(",");a!==$&&(k(a),d({genre:a,page:"1"}))},[c,$,k,d]),t("div",{className:"page-container",children:[t("div",{className:r.header,children:[t("h1",{className:r.pageTitle,children:"Search TV & Movies"}),t("p",{className:r.pageSubtitle,children:"Discover trending shows, movies, and more powered by TMDB"})]}),t("div",{className:r.filterContainer,children:[t("div",{className:r.searchBarWrapper,children:[t("div",{className:r.inputIconWrapper,children:[t(h,{name:"search",className:r.searchIcon}),t("input",{type:"text","data-virtual-keyboard":"true",className:r.searchInput,placeholder:"Search titles...",value:g,onInput:e=>H(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&A()})]}),t("div",{className:r.searchActions,children:[t("select",{value:i,onChange:e=>{J(e.currentTarget.value),N({})},className:r.providerSelect,"aria-label":"Media type",children:de.map(e=>t("option",{value:e.value,children:e.label},e.value))}),t(x,{onClick:A,className:r.searchBtn,children:"Search"}),t("button",{className:`${r.filterToggleBtn} ${b?r.active:""}`,onClick:()=>X(!b),children:[t(h,{name:"filter",size:14}),t("span",{children:"Filters"}),b?t(h,{name:"chevron-up",size:12}):t(h,{name:"chevron-down",size:12})]})]})]}),t("div",{className:`${r.advancedFilters} ${b?r.show:""}`,children:[t("div",{className:r.filterDivider}),t("div",{className:r.filterGrid,children:[t("div",{className:r.filterItem,children:[t("label",{children:"Sort By"}),t("select",{value:f,onChange:e=>E(e.currentTarget.value),children:ue.map(e=>t("option",{value:e.value,children:e.label},e.value))})]}),t("div",{className:r.filterItem,children:[t("label",{children:"Year"}),t("select",{value:y,onChange:e=>B(e.currentTarget.value),children:me.map(e=>t("option",{value:e.value,children:e.label},e.value))})]})]}),P.length>0&&t("div",{className:r.genreSection,children:[t("label",{className:r.genreLabel,children:"Genres"}),t("div",{className:r.genreContainer,children:P.map(e=>t("button",{className:`${r.genreButton} ${r[c[e.id]||""]}`,onClick:()=>te(e.id),children:e.name},e.id))})]}),t("div",{className:r.filterActions,children:[t(x,{variant:"secondary",onClick:()=>{N({}),B("ALL"),E("popularity.desc"),v(1),d({genre:"",year:"ALL",sort:"popularity.desc",page:"1"})},children:"Reset All"}),t(x,{onClick:A,className:r.searchBtn,children:"Apply Filters"})]})]})]}),Z&&t(ce,{message:ee?.message||"Search failed"}),Object.keys(c).length>0&&t("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",marginBottom:"1.5rem"},children:[t("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)",fontWeight:600},children:"Active Filters:"}),Object.entries(c).map(([e,a])=>{const n=P.find(s=>s.id===e)?.name||e;return t("span",{className:`badge ${a==="include"?"badge-primary":"badge-danger"}`,style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:[a==="include"?`+ ${n}`:`- ${n}`,t("button",{onClick:()=>{const s={...c};delete s[e],N(s)},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]},e)})]}),t("div",{className:r.resultsHeader,ref:C,children:[t("h2",{className:r.resultsTitle,children:[p?`Results for "${p}"`:S?"Browsing genres":i==="tv"?"Popular TV Shows":i==="movie"?"Popular Movies":"Trending",j>0&&t("span",{style:{fontWeight:400,color:"var(--text-tertiary)",fontSize:"0.85em",marginLeft:"0.5em"},children:["(",j.toLocaleString(),")"]})]}),T.length>0&&t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w})]}),t("div",{className:`${r.resultsGrid} ${K?r.lowEnd:""}`,children:w?t(le,{}):T.map(e=>t(se,{item:{id:e.id,title:e.title,year:e.year,type:e.type,image:e.image,vote_average:e.vote_average,adult:e.adult}},`${e.type}-${e.id}`))}),!w&&T.length===0&&t("div",{className:r.noResults,children:[t(h,{name:"search",size:48,className:r.noResultsIcon}),t("h3",{children:"No results found"}),t("p",{children:"Try adjusting your search or filters to find what you're looking for."})]}),T.length>0&&t("div",{className:r.bottomPagination,children:t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w,variant:"labeled"})})]})}export{Ae as default};
1
+ import{h as I,p as ae,A as re,d as o,T as Y,q as M,u as t}from"./vendor-core-DfaOB3Rn.js";import{I as h}from"./vendor-icons-C1Pj_eSX.js";import{P as D}from"./MediaCard-B13pU_sD.js";import{a as ne,T as se}from"./useTv-iD-DnP_2.js";import{S as le}from"./SkeletonGrid-xGtg97zD.js";import{a as ie,T as W,M as Q,a9 as oe,B as x}from"./index-CqcwUuWG.js";import{E as ce}from"./ErrorMessage-hMt90aG4.js";import{s as r}from"./Search.module-DjQZ0jox.js";import"./MediaPopupShell-BewMMT93.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-D2QxzAd5.js";import"./TvPopup-on4rxc10.js";import"./useTvLibrary-D9vDuZs7.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-CC9NocI9.js";const de=[{value:"multi",label:"All"},{value:"tv",label:"TV Shows"},{value:"movie",label:"Movies"}],ue=[{value:"popularity.desc",label:"Popularity"},{value:"vote_average.desc",label:"Top Rated"},{value:"primary_release_date.desc",label:"Newest"},{value:"primary_release_date.asc",label:"Oldest"},{value:"vote_count.desc",label:"Most Voted"}],O=new Date().getFullYear(),me=[{value:"ALL",label:"All Years"},...Array.from({length:O-1980+1},(l,m)=>({value:String(O-m),label:String(O-m)}))];function Ae(){I(()=>{document.title="Search TV & Movies - dango"},[]);const[l,m]=ae(),{lowEndMode:K}=ie(),C=re(null),[g,H]=o(l.get("q")||""),[p,U]=o(l.get("q")||""),[u,v]=o(parseInt(l.get("page")||"1",10)||1),[i,J]=o(l.get("type")||"multi"),[$,k]=o(l.get("genre")||""),[y,B]=o(l.get("year")||"ALL"),[f,E]=o(l.get("sort_by")||"popularity.desc"),[b,X]=o(!1),[c,N]=o(()=>{const e={},a=l.get("genre")||"";return a&&(e[a]="include"),e}),P=Y(()=>{if(i==="tv")return Object.entries(W).map(([a,n])=>({id:a,name:n}));if(i==="movie")return Object.entries(Q).map(([a,n])=>({id:a,name:n}));const e=new Map;for(const[a,n]of Object.entries(W))e.set(a,n);for(const[a,n]of Object.entries(Q))e.set(a,n);return Array.from(e.entries()).map(([a,n])=>({id:a,name:n}))},[i]),S=Y(()=>Object.entries(c).filter(([,a])=>a==="include").map(([a])=>a).join(","),[c]),{data:L,isLoading:w,isError:Z,error:ee}=ne({query:p,type:i,genre:S,year:y,sort_by:f,page:u}),T=L?.results||[],_=L?.total_pages||0,j=L?.total_results||0,R=u<Math.min(_,500),d=M((e={})=>{const a=new URLSearchParams,n=e.q!==void 0?e.q:p,s=e.type!==void 0?e.type:i,G=e.year!==void 0?e.year:y,V=e.sort!==void 0?e.sort:f,F=e.page!==void 0?e.page:String(u),z=e.genre!==void 0?e.genre:S;n.trim()&&a.set("q",n.trim()),s!=="multi"&&a.set("type",s),z&&a.set("genre",z),G!=="ALL"&&a.set("year",G),V!=="popularity.desc"&&a.set("sort_by",V),F!=="1"&&a.set("page",F),m(a,{replace:!0})},[p,i,y,f,u,S,m]),A=M(()=>{oe(),v(1),U(g),d({q:g,page:"1"}),window.scrollTo({top:0,behavior:"smooth"})},[g,d]),q=M(e=>{if(v(e),d({page:String(e)}),C.current){const a=C.current.getBoundingClientRect().top+window.scrollY-100;window.scrollTo({top:a,behavior:"smooth"})}},[d]),te=M(e=>{N(a=>{const n=a[e],s={...a};return n==="include"?s[e]="exclude":n==="exclude"?delete s[e]:s[e]="include",s}),v(1)},[]);return I(()=>{const a=Object.entries(c).filter(([,n])=>n==="include").map(([n])=>n).join(",");a!==$&&(k(a),d({genre:a,page:"1"}))},[c,$,k,d]),t("div",{className:"page-container",children:[t("div",{className:r.header,children:[t("h1",{className:r.pageTitle,children:"Search TV & Movies"}),t("p",{className:r.pageSubtitle,children:"Discover trending shows, movies, and more powered by TMDB"})]}),t("div",{className:r.filterContainer,children:[t("div",{className:r.searchBarWrapper,children:[t("div",{className:r.inputIconWrapper,children:[t(h,{name:"search",className:r.searchIcon}),t("input",{type:"text","data-virtual-keyboard":"true",className:r.searchInput,placeholder:"Search titles...",value:g,onInput:e=>H(e.currentTarget.value),onKeyDown:e=>e.key==="Enter"&&A()})]}),t("div",{className:r.searchActions,children:[t("select",{value:i,onChange:e=>{J(e.currentTarget.value),N({})},className:r.providerSelect,"aria-label":"Media type",children:de.map(e=>t("option",{value:e.value,children:e.label},e.value))}),t(x,{onClick:A,className:r.searchBtn,children:"Search"}),t("button",{className:`${r.filterToggleBtn} ${b?r.active:""}`,onClick:()=>X(!b),children:[t(h,{name:"filter",size:14}),t("span",{children:"Filters"}),b?t(h,{name:"chevron-up",size:12}):t(h,{name:"chevron-down",size:12})]})]})]}),t("div",{className:`${r.advancedFilters} ${b?r.show:""}`,children:[t("div",{className:r.filterDivider}),t("div",{className:r.filterGrid,children:[t("div",{className:r.filterItem,children:[t("label",{children:"Sort By"}),t("select",{value:f,onChange:e=>E(e.currentTarget.value),children:ue.map(e=>t("option",{value:e.value,children:e.label},e.value))})]}),t("div",{className:r.filterItem,children:[t("label",{children:"Year"}),t("select",{value:y,onChange:e=>B(e.currentTarget.value),children:me.map(e=>t("option",{value:e.value,children:e.label},e.value))})]})]}),P.length>0&&t("div",{className:r.genreSection,children:[t("label",{className:r.genreLabel,children:"Genres"}),t("div",{className:r.genreContainer,children:P.map(e=>t("button",{className:`${r.genreButton} ${r[c[e.id]||""]}`,onClick:()=>te(e.id),children:e.name},e.id))})]}),t("div",{className:r.filterActions,children:[t(x,{variant:"secondary",onClick:()=>{N({}),B("ALL"),E("popularity.desc"),v(1),d({genre:"",year:"ALL",sort:"popularity.desc",page:"1"})},children:"Reset All"}),t(x,{onClick:A,className:r.searchBtn,children:"Apply Filters"})]})]})]}),Z&&t(ce,{message:ee?.message||"Search failed"}),Object.keys(c).length>0&&t("div",{style:{display:"flex",flexWrap:"wrap",gap:"8px",marginBottom:"1.5rem"},children:[t("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)",fontWeight:600},children:"Active Filters:"}),Object.entries(c).map(([e,a])=>{const n=P.find(s=>s.id===e)?.name||e;return t("span",{className:`badge ${a==="include"?"badge-primary":"badge-danger"}`,style:{display:"inline-flex",alignItems:"center",gap:"6px"},children:[a==="include"?`+ ${n}`:`- ${n}`,t("button",{onClick:()=>{const s={...c};delete s[e],N(s)},style:{background:"none",border:"none",color:"inherit",cursor:"pointer"},children:"✕"})]},e)})]}),t("div",{className:r.resultsHeader,ref:C,children:[t("h2",{className:r.resultsTitle,children:[p?`Results for "${p}"`:S?"Browsing genres":i==="tv"?"Popular TV Shows":i==="movie"?"Popular Movies":"Trending",j>0&&t("span",{style:{fontWeight:400,color:"var(--text-tertiary)",fontSize:"0.85em",marginLeft:"0.5em"},children:["(",j.toLocaleString(),")"]})]}),T.length>0&&t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w})]}),t("div",{className:`${r.resultsGrid} ${K?r.lowEnd:""}`,children:w?t(le,{}):T.map(e=>t(se,{item:{id:e.id,title:e.title,year:e.year,type:e.type,image:e.image,vote_average:e.vote_average,adult:e.adult}},`${e.type}-${e.id}`))}),!w&&T.length===0&&t("div",{className:r.noResults,children:[t(h,{name:"search",size:48,className:r.noResultsIcon}),t("h3",{children:"No results found"}),t("p",{children:"Try adjusting your search or filters to find what you're looking for."})]}),T.length>0&&t("div",{className:r.bottomPagination,children:t(D,{page:u,totalPages:Math.max(1,Math.min(_,500)),canGoNext:R,onChange:q,isLoading:w,variant:"labeled"})})]})}export{Ae as default};
@@ -1 +1 @@
1
- import{o as $,d as f,h as L,T as U,u as d}from"./vendor-core-DfaOB3Rn.js";import{M as x}from"./MediaCard-Ce90T0yC.js";import{L as F}from"./LibraryListPage-B5q00Vno.js";import{R as N}from"./ResetProgressModal-CncQLVw1.js";import{T as _}from"./TvPopup-Ci4SXMWf.js";import{j as y,i as u,k as R}from"./index-BOJFs4B4.js";import{j,u as K,a as O,b as Q,f as Y,k as q,l as z,m as G,T as I}from"./useTvLibrary-F0S6WnwD.js";import"./vendor-icons-C1Pj_eSX.js";import"./MediaPopupShell-BewMMT93.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-DoPl5ONK.js";import"./SkeletonGrid-zCAxRZIz.js";import"./ErrorMessage-hMt90aG4.js";import"./LibraryListPage.module-r6k9nyT9.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-1xwHWgGv.js";const Z=["All","Continue Watching",...I],S=24;function mt(){const{filter:l="All"}=$(),[c,m]=f(1),[s,v]=f(null);L(()=>{document.title="TV Watchlist - dango"},[]),L(()=>{m(1)},[l]);const o=l==="Continue Watching",r=j(o?"All":l,c,S),i=K(100),T=O(),P=Q(),k=Y(),w=q(),C=z(),B=G(),M=U(()=>o?(i.data?.data??[]).map(t=>{const a=t.currentTime??0,e=t.duration??0,g=t.season??1,h=t.episode??1,n=t.mediaType==="movie",p=n?"Movie":`S${g} E${h}`,b=t.completed===1||e>0&&a>=e*.8;return{key:t.id,libId:t.id,tmdbId:t.tmdbId??0,mediaType:t.mediaType,title:t.title||"",poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.watchlistStatus??"",badge:p,progressPercent:b?100:e>0?a/e*100:0,progressLabel:e>0?b?"Watched":n?`${u(a)} / ${u(e)}`:`${p} · ${u(a)} / ${u(e)}`:p,watchTarget:y(t.mediaType,t.tmdbId??0,n?void 0:g,n?void 0:h)}}):(r.data?.data??[]).map(t=>({key:t.id,libId:t.id,tmdbId:t.tmdbId,mediaType:t.mediaType,title:t.title,poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.status,badge:t.lastSeason&&t.lastEpisode?`S${t.lastSeason} E${t.lastEpisode}`:void 0,progressPercent:void 0,progressLabel:void 0,watchTarget:y(t.mediaType,t.tmdbId,t.lastSeason??void 0,t.lastEpisode??void 0)})),[o,i.data,r.data]),W=o?i.data?.total??0:r.data?.total??0,E=o?i.isLoading:r.isLoading,A=o?i.error:r.error,V=t=>{s&&(P.mutate({mediaId:s.libId}),t&&T.mutate(s.libId))};return d(F,{headerTitle:"My TV Watchlist",headerSubtitle:"Track and manage your movies and shows",filters:Z,filterBy:l,filterBasePath:"/tv-watchlist",continueFilter:"Continue Watching",statusOptions:[...I],entries:M,total:W,isLoading:E,error:A,page:c,pageSize:S,onPageChange:m,emptyTitle:"Your TV watchlist is looking a bit empty",emptyFilteredText:"No titles match this filter.",emptyAllText:"Let's find something to watch!",browseLabel:"Browse TV & Movies",browseTarget:"/tv",removeListLabel:"Remove from TV Watchlist",listNoun:"TV watchlist",skipConfirmKey:"tvSkipRemoveConfirmation",onBulkStatus:(t,a)=>w.mutate({ids:t,status:a}),onBulkRemove:t=>{o?B.mutate(t):C.mutate(t)},onStatusChange:(t,a)=>k.mutate({id:t,status:a}),onRemoveItem:t=>T.mutate(t),renderCard:t=>d(x,{item:{id:t.libId,title:t.title,thumbnail:t.poster,typeBadge:t.mediaType==="movie"?"Movie":"TV",chapterBadge:t.badge??null,isAdult:t.adult},linkTo:t.watchTarget,hoverIcon:"play",progress:t.progressPercent!==void 0&&t.progressLabel?{percent:t.progressPercent,label:t.progressLabel}:void 0,showProgress:o,metaRow:t.year?d("span",{style:{opacity:.75},children:t.year}):void 0,onRemove:o?()=>v(t):void 0,renderPopup:(a,e)=>d(_,{item:{id:t.tmdbId??0,title:t.title||"",year:t.year||"",type:t.mediaType||"tv",image:t.poster||""},anchorRect:a,onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,onRequestClose:e.close})}),modals:d(N,{isOpen:!!s,itemName:s?.title,progressKind:"watch",listLabel:"my TV watchlist",onClose:()=>{v(null)},onConfirm:V})})}export{mt as default};
1
+ import{o as $,d as f,h as L,T as U,u as d}from"./vendor-core-DfaOB3Rn.js";import{M as x}from"./MediaCard-B13pU_sD.js";import{L as F}from"./LibraryListPage-DJcL0lfR.js";import{R as N}from"./ResetProgressModal-Dw-OK0wI.js";import{T as _}from"./TvPopup-on4rxc10.js";import{k as y,j as u,l as R}from"./index-CqcwUuWG.js";import{j,u as K,a as O,b as Q,f as Y,k as q,l as z,m as G,T as I}from"./useTvLibrary-D9vDuZs7.js";import"./vendor-icons-C1Pj_eSX.js";import"./MediaPopupShell-BewMMT93.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./MatureConsentModal-D2QxzAd5.js";import"./SkeletonGrid-xGtg97zD.js";import"./ErrorMessage-hMt90aG4.js";import"./LibraryListPage.module-r6k9nyT9.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-CC9NocI9.js";const Z=["All","Continue Watching",...I],S=24;function mt(){const{filter:l="All"}=$(),[c,m]=f(1),[s,v]=f(null);L(()=>{document.title="TV Watchlist - dango"},[]),L(()=>{m(1)},[l]);const o=l==="Continue Watching",r=j(o?"All":l,c,S),i=K(100),T=O(),P=Q(),k=Y(),w=q(),C=z(),B=G(),M=U(()=>o?(i.data?.data??[]).map(t=>{const a=t.currentTime??0,e=t.duration??0,g=t.season??1,h=t.episode??1,n=t.mediaType==="movie",p=n?"Movie":`S${g} E${h}`,b=t.completed===1||e>0&&a>=e*.8;return{key:t.id,libId:t.id,tmdbId:t.tmdbId??0,mediaType:t.mediaType,title:t.title||"",poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.watchlistStatus??"",badge:p,progressPercent:b?100:e>0?a/e*100:0,progressLabel:e>0?b?"Watched":n?`${u(a)} / ${u(e)}`:`${p} · ${u(a)} / ${u(e)}`:p,watchTarget:y(t.mediaType,t.tmdbId??0,n?void 0:g,n?void 0:h)}}):(r.data?.data??[]).map(t=>({key:t.id,libId:t.id,tmdbId:t.tmdbId,mediaType:t.mediaType,title:t.title,poster:t.poster||"",year:t.year,adult:R({adult:t.adult===1}),status:t.status,badge:t.lastSeason&&t.lastEpisode?`S${t.lastSeason} E${t.lastEpisode}`:void 0,progressPercent:void 0,progressLabel:void 0,watchTarget:y(t.mediaType,t.tmdbId,t.lastSeason??void 0,t.lastEpisode??void 0)})),[o,i.data,r.data]),W=o?i.data?.total??0:r.data?.total??0,E=o?i.isLoading:r.isLoading,A=o?i.error:r.error,V=t=>{s&&(P.mutate({mediaId:s.libId}),t&&T.mutate(s.libId))};return d(F,{headerTitle:"My TV Watchlist",headerSubtitle:"Track and manage your movies and shows",filters:Z,filterBy:l,filterBasePath:"/tv-watchlist",continueFilter:"Continue Watching",statusOptions:[...I],entries:M,total:W,isLoading:E,error:A,page:c,pageSize:S,onPageChange:m,emptyTitle:"Your TV watchlist is looking a bit empty",emptyFilteredText:"No titles match this filter.",emptyAllText:"Let's find something to watch!",browseLabel:"Browse TV & Movies",browseTarget:"/tv",removeListLabel:"Remove from TV Watchlist",listNoun:"TV watchlist",skipConfirmKey:"tvSkipRemoveConfirmation",onBulkStatus:(t,a)=>w.mutate({ids:t,status:a}),onBulkRemove:t=>{o?B.mutate(t):C.mutate(t)},onStatusChange:(t,a)=>k.mutate({id:t,status:a}),onRemoveItem:t=>T.mutate(t),renderCard:t=>d(x,{item:{id:t.libId,title:t.title,thumbnail:t.poster,typeBadge:t.mediaType==="movie"?"Movie":"TV",chapterBadge:t.badge??null,isAdult:t.adult},linkTo:t.watchTarget,hoverIcon:"play",progress:t.progressPercent!==void 0&&t.progressLabel?{percent:t.progressPercent,label:t.progressLabel}:void 0,showProgress:o,metaRow:t.year?d("span",{style:{opacity:.75},children:t.year}):void 0,onRemove:o?()=>v(t):void 0,renderPopup:(a,e)=>d(_,{item:{id:t.tmdbId??0,title:t.title||"",year:t.year||"",type:t.mediaType||"tv",image:t.poster||""},anchorRect:a,onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave,onRequestClose:e.close})}),modals:d(N,{isOpen:!!s,itemName:s?.title,progressKind:"watch",listLabel:"my TV watchlist",onClose:()=>{v(null)},onConfirm:V})})}export{mt as default};
@@ -1 +1 @@
1
- import{d as w,A as E,h as v,q as N,$ as D,u as o}from"./vendor-core-DfaOB3Rn.js";import{p as x}from"./index-BOJFs4B4.js";import"./vendor-query-BBT5_sHx.js";import"./vendor-icons-C1Pj_eSX.js";const O="_keyboard_1l8yf_1",R="_small_1l8yf_18",T="_medium_1l8yf_25",q="_large_1l8yf_32",U="_topBar_1l8yf_39",V="_dragHandle_1l8yf_48",W="_grip_1l8yf_59",X="_topButton_1l8yf_67",Y="_key_1l8yf_1",j="_closeButton_1l8yf_98",A="_keys_1l8yf_104",F="_row_1l8yf_111",J="_wideKey_1l8yf_132",P="_spaceKey_1l8yf_136",G="_spaceIcon_1l8yf_144",Q="_activeKey_1l8yf_153",t={keyboard:O,small:R,medium:T,large:q,topBar:U,dragHandle:V,grip:W,topButton:X,key:Y,closeButton:j,keys:A,row:F,wideKey:J,spaceKey:P,spaceIcon:G,activeKey:Q},$="virtual-keyboard-state",b=["small","medium","large"],Z=["1","2","3","4","5","6","7","8","9","0"],ee=["!","@","#","$","%","^","&","*","(",")"],te=[["q","w","e","r","t","y","u","i","o","p"],["a","s","d","f","g","h","j","k","l"],["z","x","c","v","b","n","m"]],ne=()=>{const i={position:{x:Math.max(12,window.innerWidth-690),y:Math.max(90,window.innerHeight-330)},size:"medium"};try{const c=x.getItem($);if(!c)return i;const s=JSON.parse(c);return{position:s.position&&Number.isFinite(s.position.x)&&Number.isFinite(s.position.y)?s.position:i.position,size:s.size&&b.includes(s.size)?s.size:i.size}}catch{return i}},K=(i,c)=>{const s=c?.offsetWidth??650,r=c?.offsetHeight??270;return{x:Math.min(Math.max(8,i.x),Math.max(8,window.innerWidth-s-8)),y:Math.min(Math.max(8,i.y),Math.max(8,window.innerHeight-r-8))}};function re({activeInputRef:i,isVisible:c,onClose:s}){const[{position:r,size:l},h]=w(ne),[k,z]=w(!1),[g,S]=w(!1),f=E(null),u=E(null);v(()=>{x.setItem($,JSON.stringify({position:r,size:l}))},[r,l]),v(()=>{const e=()=>{h(n=>({...n,position:K(n.position,f.current)}))};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]);const _=()=>i.current&&document.contains(i.current)?i.current:document.activeElement instanceof HTMLInputElement?document.activeElement:null,d=e=>{const n=_();if(!n)return;const a=n.selectionStart??n.value.length,p=n.selectionEnd??n.value.length;n.setRangeText(e,a,p,"end"),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()},M=()=>{const e=_();if(!e)return;const n=e.selectionStart??e.value.length,a=e.selectionEnd??e.value.length;n===a&&n===0||(e.setRangeText("",n===a?n-1:n,a,"end"),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus())},B=()=>{const e=_();if(!e){s();return}const n=e.form;n?n.requestSubmit():e.dispatchEvent(new KeyboardEvent("keydown",{key:"Enter",bubbles:!0})),s()},C=e=>{e.preventDefault()},y=N(e=>{if(!u.current)return;const n={x:e.clientX-u.current.x,y:e.clientY-u.current.y};h(a=>({...a,position:K(n,f.current)}))},[]),m=N(()=>{u.current=null,window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",m)},[y]),L=e=>{e.preventDefault(),u.current={x:e.clientX-r.x,y:e.clientY-r.y},window.addEventListener("mousemove",y),window.addEventListener("mouseup",m)};if(v(()=>()=>{window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",m)},[y,m]),!c)return null;const H=g?ee:Z,I=()=>{h(e=>{const n=b[(b.indexOf(e.size)+1)%b.length];return{...e,size:n}})};return D(o("div",{ref:f,className:`${t.keyboard} ${t[l]}`,style:{left:r.x,top:r.y},onMouseDown:C,"data-virtual-keyboard-root":!0,children:[o("div",{className:t.topBar,children:[o("div",{className:t.dragHandle,onMouseDown:L,"aria-label":"Move virtual keyboard",children:[o("span",{className:t.grip,"aria-hidden":"true"}),o("span",{children:"Virtual Keyboard"})]}),o("button",{type:"button",className:t.topButton,onClick:I,children:["Size: ",l[0].toUpperCase()+l.slice(1)]}),o("button",{type:"button",className:`${t.topButton} ${t.closeButton}`,onClick:s,children:"X"})]}),o("div",{className:t.keys,children:[o("div",{className:t.row,children:[H.map(e=>o("button",{type:"button",className:t.key,onClick:()=>d(e),children:e},e)),o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:M,"aria-label":"Backspace",children:"⟵"})]}),te.map((e,n)=>o("div",{className:t.row,children:[e.map(a=>{const p=k?a.toUpperCase():a;return o("button",{type:"button",className:t.key,onClick:()=>d(p),children:p},a)}),n===1&&o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:B,children:"Enter"})]},e.join(""))),o("div",{className:t.row,children:[o("button",{type:"button",className:`${t.key} ${t.wideKey} ${g?t.activeKey:""}`,onClick:()=>S(e=>!e),children:"Ctrl"}),o("button",{type:"button",className:`${t.key} ${t.wideKey} ${k?t.activeKey:""}`,onClick:()=>z(e=>!e),children:"Shift"}),o("button",{type:"button",className:`${t.key} ${t.spaceKey}`,onClick:()=>d(" "),"aria-label":"Space",children:o("span",{className:t.spaceIcon})}),o("button",{type:"button",className:t.key,onClick:()=>d("."),children:"."}),o("button",{type:"button",className:t.key,onClick:()=>d("-"),children:"-"})]})]})]}),document.body)}export{re as default};
1
+ import{d as w,A as E,h as v,q as N,$ as D,u as o}from"./vendor-core-DfaOB3Rn.js";import{p as x}from"./index-CqcwUuWG.js";import"./vendor-query-BBT5_sHx.js";import"./vendor-icons-C1Pj_eSX.js";const O="_keyboard_1l8yf_1",R="_small_1l8yf_18",T="_medium_1l8yf_25",q="_large_1l8yf_32",U="_topBar_1l8yf_39",V="_dragHandle_1l8yf_48",W="_grip_1l8yf_59",X="_topButton_1l8yf_67",Y="_key_1l8yf_1",j="_closeButton_1l8yf_98",A="_keys_1l8yf_104",F="_row_1l8yf_111",J="_wideKey_1l8yf_132",P="_spaceKey_1l8yf_136",G="_spaceIcon_1l8yf_144",Q="_activeKey_1l8yf_153",t={keyboard:O,small:R,medium:T,large:q,topBar:U,dragHandle:V,grip:W,topButton:X,key:Y,closeButton:j,keys:A,row:F,wideKey:J,spaceKey:P,spaceIcon:G,activeKey:Q},$="virtual-keyboard-state",b=["small","medium","large"],Z=["1","2","3","4","5","6","7","8","9","0"],ee=["!","@","#","$","%","^","&","*","(",")"],te=[["q","w","e","r","t","y","u","i","o","p"],["a","s","d","f","g","h","j","k","l"],["z","x","c","v","b","n","m"]],ne=()=>{const i={position:{x:Math.max(12,window.innerWidth-690),y:Math.max(90,window.innerHeight-330)},size:"medium"};try{const c=x.getItem($);if(!c)return i;const s=JSON.parse(c);return{position:s.position&&Number.isFinite(s.position.x)&&Number.isFinite(s.position.y)?s.position:i.position,size:s.size&&b.includes(s.size)?s.size:i.size}}catch{return i}},K=(i,c)=>{const s=c?.offsetWidth??650,r=c?.offsetHeight??270;return{x:Math.min(Math.max(8,i.x),Math.max(8,window.innerWidth-s-8)),y:Math.min(Math.max(8,i.y),Math.max(8,window.innerHeight-r-8))}};function re({activeInputRef:i,isVisible:c,onClose:s}){const[{position:r,size:l},h]=w(ne),[k,z]=w(!1),[g,S]=w(!1),f=E(null),u=E(null);v(()=>{x.setItem($,JSON.stringify({position:r,size:l}))},[r,l]),v(()=>{const e=()=>{h(n=>({...n,position:K(n.position,f.current)}))};return window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)},[]);const _=()=>i.current&&document.contains(i.current)?i.current:document.activeElement instanceof HTMLInputElement?document.activeElement:null,d=e=>{const n=_();if(!n)return;const a=n.selectionStart??n.value.length,p=n.selectionEnd??n.value.length;n.setRangeText(e,a,p,"end"),n.dispatchEvent(new Event("input",{bubbles:!0})),n.focus()},M=()=>{const e=_();if(!e)return;const n=e.selectionStart??e.value.length,a=e.selectionEnd??e.value.length;n===a&&n===0||(e.setRangeText("",n===a?n-1:n,a,"end"),e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus())},B=()=>{const e=_();if(!e){s();return}const n=e.form;n?n.requestSubmit():e.dispatchEvent(new KeyboardEvent("keydown",{key:"Enter",bubbles:!0})),s()},C=e=>{e.preventDefault()},y=N(e=>{if(!u.current)return;const n={x:e.clientX-u.current.x,y:e.clientY-u.current.y};h(a=>({...a,position:K(n,f.current)}))},[]),m=N(()=>{u.current=null,window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",m)},[y]),L=e=>{e.preventDefault(),u.current={x:e.clientX-r.x,y:e.clientY-r.y},window.addEventListener("mousemove",y),window.addEventListener("mouseup",m)};if(v(()=>()=>{window.removeEventListener("mousemove",y),window.removeEventListener("mouseup",m)},[y,m]),!c)return null;const H=g?ee:Z,I=()=>{h(e=>{const n=b[(b.indexOf(e.size)+1)%b.length];return{...e,size:n}})};return D(o("div",{ref:f,className:`${t.keyboard} ${t[l]}`,style:{left:r.x,top:r.y},onMouseDown:C,"data-virtual-keyboard-root":!0,children:[o("div",{className:t.topBar,children:[o("div",{className:t.dragHandle,onMouseDown:L,"aria-label":"Move virtual keyboard",children:[o("span",{className:t.grip,"aria-hidden":"true"}),o("span",{children:"Virtual Keyboard"})]}),o("button",{type:"button",className:t.topButton,onClick:I,children:["Size: ",l[0].toUpperCase()+l.slice(1)]}),o("button",{type:"button",className:`${t.topButton} ${t.closeButton}`,onClick:s,children:"X"})]}),o("div",{className:t.keys,children:[o("div",{className:t.row,children:[H.map(e=>o("button",{type:"button",className:t.key,onClick:()=>d(e),children:e},e)),o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:M,"aria-label":"Backspace",children:"⟵"})]}),te.map((e,n)=>o("div",{className:t.row,children:[e.map(a=>{const p=k?a.toUpperCase():a;return o("button",{type:"button",className:t.key,onClick:()=>d(p),children:p},a)}),n===1&&o("button",{type:"button",className:`${t.key} ${t.wideKey}`,onClick:B,children:"Enter"})]},e.join(""))),o("div",{className:t.row,children:[o("button",{type:"button",className:`${t.key} ${t.wideKey} ${g?t.activeKey:""}`,onClick:()=>S(e=>!e),children:"Ctrl"}),o("button",{type:"button",className:`${t.key} ${t.wideKey} ${k?t.activeKey:""}`,onClick:()=>z(e=>!e),children:"Shift"}),o("button",{type:"button",className:`${t.key} ${t.spaceKey}`,onClick:()=>d(" "),"aria-label":"Space",children:o("span",{className:t.spaceIcon})}),o("button",{type:"button",className:t.key,onClick:()=>d("."),children:"."}),o("button",{type:"button",className:t.key,onClick:()=>d("-"),children:"-"})]})]})]}),document.body)}export{re as default};
@@ -1 +1 @@
1
- import{c as h,d as s,u as e}from"./vendor-core-DfaOB3Rn.js";import{a7 as d,B as m}from"./index-BOJFs4B4.js";import{W as u,s as p,a as g}from"./WatchAlongPanel-G2j2eopw.js";import"./vendor-query-BBT5_sHx.js";import"./vendor-icons-C1Pj_eSX.js";function b(){const o=d(),c=h(),[t,l]=s(c.hash.slice(1)),[n,a]=s("");return e("div",{style:{maxWidth:640,margin:"2rem auto",padding:"0 1rem"},children:[e("h1",{children:"Watch along"}),e("p",{children:"Watch with friends across the internet. The host chooses the episode, provider, and source, and controls playback. Your dango streams your own video."}),o.session&&e(u,{}),!o.session&&e("form",{className:p.panel,onSubmit:r=>{r.preventDefault();try{o.join(t),a("")}catch(i){a(i instanceof Error?i.message:"Could not join room")}},children:[e(g,{}),e("label",{htmlFor:"watch-invite",children:"Invite link or room code"}),e("input",{id:"watch-invite",value:t,onChange:r=>l(r.currentTarget.value),required:!0,autoComplete:"off"}),e("p",{children:"Joining shares your connection and playback readiness with the room service. Start a room from an episode using a direct HLS source."}),e(m,{type:"submit",disabled:!o.workerUrl,style:{marginTop:"1rem"},children:"Join room"}),!o.workerUrl&&e("p",{children:"Watch along is unavailable. The server needs a watch-along service URL."}),n&&e("p",{role:"alert",children:n})]})]})}export{b as default};
1
+ import{c as h,d as s,u as e}from"./vendor-core-DfaOB3Rn.js";import{a7 as d,B as m}from"./index-CqcwUuWG.js";import{W as u,s as p,a as g}from"./WatchAlongPanel-D_ToyGjh.js";import"./vendor-query-BBT5_sHx.js";import"./vendor-icons-C1Pj_eSX.js";function b(){const o=d(),c=h(),[t,l]=s(c.hash.slice(1)),[n,a]=s("");return e("div",{style:{maxWidth:640,margin:"2rem auto",padding:"0 1rem"},children:[e("h1",{children:"Watch along"}),e("p",{children:"Watch with friends across the internet. The host chooses the episode, provider, and source, and controls playback. Your dango streams your own video."}),o.session&&e(u,{}),!o.session&&e("form",{className:p.panel,onSubmit:r=>{r.preventDefault();try{o.join(t),a("")}catch(i){a(i instanceof Error?i.message:"Could not join room")}},children:[e(g,{}),e("label",{htmlFor:"watch-invite",children:"Invite link or room code"}),e("input",{id:"watch-invite",value:t,onChange:r=>l(r.currentTarget.value),required:!0,autoComplete:"off"}),e("p",{children:"Joining shares your connection and playback readiness with the room service. Start a room from an episode using a direct HLS source."}),e(m,{type:"submit",disabled:!o.workerUrl,style:{marginTop:"1rem"},children:"Join room"}),!o.workerUrl&&e("p",{children:"Watch along is unavailable. The server needs a watch-along service URL."}),n&&e("p",{role:"alert",children:n})]})]})}export{b as default};
@@ -1 +1 @@
1
- import{d as h,A as _,h as z,u as s,L as C}from"./vendor-core-DfaOB3Rn.js";import{a7 as g,B as r}from"./index-BOJFs4B4.js";const N="_panel_ntzz0_1",b="_summary_ntzz0_10",k="_heading_ntzz0_20",x="_actions_ntzz0_21",T="_members_ntzz0_22",A="_name_ntzz0_29",o={panel:N,summary:b,heading:k,actions:x,members:T,name:A};function L(){const t=g();return s("label",{className:o.name,children:["Display name",s("input",{value:t.displayName,onChange:a=>t.setDisplayName(a.currentTarget.value),maxLength:32,placeholder:"Your name (optional)",autoComplete:"nickname"}),s("small",{children:"Remembered for this profile on this browser."})]})}function D({playback:t,onCreate:a,needsPlayback:l,onEnablePlayback:p}){const e=g(),[y,m]=h(!1),[d,i]=h(""),[v,f]=h(!1),c=_(null);z(()=>{c.current&&(e.session||l)&&(c.current.open=!0)},[e.session,l]);const u=e.session?`${e.workerUrl}/join#${e.session.id}.${e.session.guestToken}`:"";return s("details",{ref:c,className:o.panel,"aria-label":"Watch along",children:[s("summary",{className:o.summary,children:["Watch along",e.session?e.session.host?" · You are hosting":" · Following host":""]}),s("div",{className:o.heading,children:e.session?s("div",{className:o.actions,children:[s(r,{size:"sm",variant:"secondary",onClick:async()=>{f(!0);try{await navigator.clipboard.writeText(u),i("Invite copied")}catch{i("Copy the invite below")}},children:"Copy invite"}),s(r,{size:"sm",variant:"ghost",onClick:e.leave,children:e.session.host?"End room":"Leave room"})]}):s("div",{className:o.actions,children:[a&&s(r,{size:"sm",loading:y,disabled:!t||!e.workerUrl,onClick:async()=>{if(t){m(!0),i("");try{a(),await e.create({...t,playing:!1})}catch(n){i(n instanceof Error?n.message:"Could not create room")}finally{m(!1)}}},children:"Create room"}),s(C,{to:"/watch-along",children:"Join a room"})]})}),s(L,{}),!e.session&&s("p",{children:"Direct HLS only. Each viewer needs their own dango. Room controls use the shared watch-along service."}),e.session&&s("p",{children:[e.connected?e.room?.hostOnline?"Connected":"Host disconnected. Room closes after 60 seconds unless they reconnect":"Connecting…"," ","· Provider and source follow the host. Volume and subtitles stay yours."]}),e.room&&s("p",{children:[e.session?.host&&"End the room when you are finished watching. ","Rooms automatically close six hours after creation. This room expires at"," ",s("time",{dateTime:new Date(e.room.expiresAt).toISOString(),children:new Date(e.room.expiresAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}),", even if playback is still active."]}),e.room&&s("ul",{className:o.members,children:e.room.members.map((n,w)=>s("li",{children:[n.name||(n.host?"Host":`Guest ${w+1}`),n.name&&n.host?" (host)":"",n.id===e.selfId?" (you)":"",": ",n.status]},n.id))}),l&&s(r,{size:"sm",onClick:p,children:"Enable playback"}),v&&e.session&&s("input",{"aria-label":"Room invite",readOnly:!0,value:u,onFocus:n=>n.currentTarget.select()}),(e.error||d)&&s("p",{role:"status",children:e.error||d})]})}export{D as W,L as a,o as s};
1
+ import{d as h,A as _,h as z,u as s,L as C}from"./vendor-core-DfaOB3Rn.js";import{a7 as g,B as r}from"./index-CqcwUuWG.js";const N="_panel_ntzz0_1",b="_summary_ntzz0_10",k="_heading_ntzz0_20",x="_actions_ntzz0_21",T="_members_ntzz0_22",A="_name_ntzz0_29",o={panel:N,summary:b,heading:k,actions:x,members:T,name:A};function L(){const t=g();return s("label",{className:o.name,children:["Display name",s("input",{value:t.displayName,onChange:a=>t.setDisplayName(a.currentTarget.value),maxLength:32,placeholder:"Your name (optional)",autoComplete:"nickname"}),s("small",{children:"Remembered for this profile on this browser."})]})}function D({playback:t,onCreate:a,needsPlayback:l,onEnablePlayback:p}){const e=g(),[y,m]=h(!1),[d,i]=h(""),[v,f]=h(!1),c=_(null);z(()=>{c.current&&(e.session||l)&&(c.current.open=!0)},[e.session,l]);const u=e.session?`${e.workerUrl}/join#${e.session.id}.${e.session.guestToken}`:"";return s("details",{ref:c,className:o.panel,"aria-label":"Watch along",children:[s("summary",{className:o.summary,children:["Watch along",e.session?e.session.host?" · You are hosting":" · Following host":""]}),s("div",{className:o.heading,children:e.session?s("div",{className:o.actions,children:[s(r,{size:"sm",variant:"secondary",onClick:async()=>{f(!0);try{await navigator.clipboard.writeText(u),i("Invite copied")}catch{i("Copy the invite below")}},children:"Copy invite"}),s(r,{size:"sm",variant:"ghost",onClick:e.leave,children:e.session.host?"End room":"Leave room"})]}):s("div",{className:o.actions,children:[a&&s(r,{size:"sm",loading:y,disabled:!t||!e.workerUrl,onClick:async()=>{if(t){m(!0),i("");try{a(),await e.create({...t,playing:!1})}catch(n){i(n instanceof Error?n.message:"Could not create room")}finally{m(!1)}}},children:"Create room"}),s(C,{to:"/watch-along",children:"Join a room"})]})}),s(L,{}),!e.session&&s("p",{children:"Direct HLS only. Each viewer needs their own dango. Room controls use the shared watch-along service."}),e.session&&s("p",{children:[e.connected?e.room?.hostOnline?"Connected":"Host disconnected. Room closes after 60 seconds unless they reconnect":"Connecting…"," ","· Provider and source follow the host. Volume and subtitles stay yours."]}),e.room&&s("p",{children:[e.session?.host&&"End the room when you are finished watching. ","Rooms automatically close six hours after creation. This room expires at"," ",s("time",{dateTime:new Date(e.room.expiresAt).toISOString(),children:new Date(e.room.expiresAt).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}),", even if playback is still active."]}),e.room&&s("ul",{className:o.members,children:e.room.members.map((n,w)=>s("li",{children:[n.name||(n.host?"Host":`Guest ${w+1}`),n.name&&n.host?" (host)":"",n.id===e.selfId?" (you)":"",": ",n.status]},n.id))}),l&&s(r,{size:"sm",onClick:p,children:"Enable playback"}),v&&e.session&&s("input",{"aria-label":"Room invite",readOnly:!0,value:u,onFocus:n=>n.currentTarget.select()}),(e.error||d)&&s("p",{role:"status",children:e.error||d})]})}export{D as W,L as a,o as s};