@serifpersia/dango 3.7.2 → 3.7.3

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 (58) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-CoPx634q.js → AnimeCard-BVufFeLC.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-COVCRujg.js → AnimeInfo-Dihook4h.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-BwlKpRXY.js → AnimeInfoPage-K0ErjilQ.js} +2 -2
  5. package/client/dist/assets/{Asmr-nOUcDsWe.js → Asmr-CP7vVwsh.js} +1 -1
  6. package/client/dist/assets/{AsmrResetProgressModal-Mj1PYE2c.js → AsmrResetProgressModal-cYO4Sr2k.js} +1 -1
  7. package/client/dist/assets/{Home-wi0a_BDQ.js → Home-BYuAVKgx.js} +1 -1
  8. package/client/dist/assets/{Insights-MLCDyTnY.js → Insights-Bx01GySp.js} +1 -1
  9. package/client/dist/assets/{LibraryListPage-CRqv737t.js → LibraryListPage-BnrEDG8j.js} +1 -1
  10. package/client/dist/assets/{ListeningList-8dzhiDeb.js → ListeningList-kRSLAo3B.js} +1 -1
  11. package/client/dist/assets/{Manga-dkD-uWJk.js → Manga-COhyMd3K.js} +1 -1
  12. package/client/dist/assets/{MangaInfoPage-nCeWZNcO.js → MangaInfoPage-LTEvl_nL.js} +1 -1
  13. package/client/dist/assets/{MangaReadPage-NdDNCyLg.js → MangaReadPage-sEwzyBQ7.js} +1 -1
  14. package/client/dist/assets/{MangaResetProgressModal-C28AiLJl.js → MangaResetProgressModal-CbMR36Zu.js} +1 -1
  15. package/client/dist/assets/{Mature-D5WSkhIJ.js → Mature-CMvs_-gf.js} +1 -1
  16. package/client/dist/assets/{MatureConsentModal-BsdpNeXA.js → MatureConsentModal-BnB-RHYQ.js} +1 -1
  17. package/client/dist/assets/{MediaCard-C1jNesfK.js → MediaCard-hWGCEHWx.js} +1 -1
  18. package/client/dist/assets/OptionListMenu-onM2KK2X.js +1 -0
  19. package/client/dist/assets/Player-2YKevlG4.js +56 -0
  20. package/client/dist/assets/PlayerSettings-BfSv-hut.js +1 -0
  21. package/client/dist/assets/{QueueOptionsButton-DNzKPzPw.js → QueueOptionsButton-B4Re8F3V.js} +1 -1
  22. package/client/dist/assets/{QueueRail-BWcDVSHd.js → QueueRail-Dkx_M6ng.js} +1 -1
  23. package/client/dist/assets/{ReadingList-zkFp3wpF.js → ReadingList-C--ZvTe2.js} +1 -1
  24. package/client/dist/assets/{ResetProgressModal-BYNYqwwl.js → ResetProgressModal-BuESoxbY.js} +1 -1
  25. package/client/dist/assets/{Search-yDP_wGJ1.js → Search-CEErwr88.js} +1 -1
  26. package/client/dist/assets/{Settings-BpKwWesn.js → Settings-C-QEEujv.js} +1 -1
  27. package/client/dist/assets/{SkeletonGrid-CYJeh04P.js → SkeletonGrid-QWMGLCGp.js} +1 -1
  28. package/client/dist/assets/{Trackers-D2KUt71k.js → Trackers-1i4Hd5D3.js} +1 -1
  29. package/client/dist/assets/Tv-C6F9655r.js +4 -0
  30. package/client/dist/assets/{TvInfo-D_4QdgV4.js → TvInfo-BajXP7JJ.js} +1 -1
  31. package/client/dist/assets/{TvPopup-DHXB5ZSF.js → TvPopup-DZtX79Ol.js} +1 -1
  32. package/client/dist/assets/{TvSearch-COwVoGru.js → TvSearch-DcWcxRb1.js} +1 -1
  33. package/client/dist/assets/{TvWatchlist-CU3r-NO5.js → TvWatchlist-Cf_25dKi.js} +1 -1
  34. package/client/dist/assets/{Watchlist-DHyuTLJG.js → Watchlist-DBmU8PNR.js} +1 -1
  35. package/client/dist/assets/{hls-DOAVt6Ry.js → hls-Bi-DS5KL.js} +1 -1
  36. package/client/dist/assets/{index-BLh_CXtu.js → index-DB81Su4I.js} +2 -2
  37. package/client/dist/assets/{libraryInvalidation-AzFLnbjH.js → libraryInvalidation-DI-v-DQ1.js} +1 -1
  38. package/client/dist/assets/playbackCompletion-IPHm9fp5.js +1 -0
  39. package/client/dist/assets/{useAnimeInfoData-MPNJXLaM.js → useAnimeInfoData-DpUA78Mv.js} +1 -1
  40. package/client/dist/assets/{useAsmr-2dFEmQD_.js → useAsmr-BwyYDnlP.js} +1 -1
  41. package/client/dist/assets/{useAsmrPopup-N2vUf3Pw.js → useAsmrPopup-BrrEaBlV.js} +1 -1
  42. package/client/dist/assets/{useMangaLibrary-B3Ni34a7.js → useMangaLibrary-BAUaug-u.js} +1 -1
  43. package/client/dist/assets/{useMangaPopup-h8NHEPUk.js → useMangaPopup-3Lx5tEub.js} +1 -1
  44. package/client/dist/assets/usePlaybackEnd-CuDnNZ8o.js +10 -0
  45. package/client/dist/assets/{useProviders-z8L8GKy0.js → useProviders-CKqOSX5-.js} +1 -1
  46. package/client/dist/assets/{useTv-D4zQ1BsQ.js → useTv-CZB47zUF.js} +1 -1
  47. package/client/dist/assets/{useTvLibrary-B4vcRzQc.js → useTvLibrary-BGz7Unv_.js} +1 -1
  48. package/client/dist/index.html +1 -1
  49. package/package.json +2 -2
  50. package/server/dist/server.js +2 -2
  51. package/server/package.json +1 -1
  52. package/client/dist/assets/AvSyncCalibrator-C5GxpyPE.js +0 -10
  53. package/client/dist/assets/OptionListMenu-CIvW5WmO.js +0 -1
  54. package/client/dist/assets/Player-PGj8YYO8.js +0 -56
  55. package/client/dist/assets/PlayerSettings-CAYfF0sA.js +0 -1
  56. package/client/dist/assets/Tv-Ul3jFq-x.js +0 -4
  57. package/client/dist/assets/playbackCompletion-DuUs8u-8.js +0 -1
  58. /package/client/dist/assets/{AvSyncCalibrator-BtUHM1mW.css → usePlaybackEnd-BtUHM1mW.css} +0 -0
@@ -891,7 +891,7 @@ If you want to call this function on the server, see https://trpc.io/docs/v11/se
891
891
  WHERE p.rn = 1
892
892
  AND (l.status IS NULL OR l.status = 'Watching')
893
893
  ORDER BY p.updatedAt DESC, p.progressRowid DESC
894
- ${y.raw(r)}`)}};function Lgt(e){return String(e).toLowerCase()==="movie"?"movie":"tv"}var Mgt=()=>pe(e=>{let t=ye(e);return{tmdbId:t.tmdbId,mediaType:t.mediaType,id:t.id,title:t.title,poster:t.poster,backdrop:t.backdrop,year:t.year,overview:t.overview,status:t.status,adult:t.adult}}),Oye=At(om({db:e=>e.tvDb,write:rh,repo:gx,progress:{deleteByKey:(e,t)=>gu.deleteByKey(e,t),deleteMany:(e,t)=>gu.deleteMany(e,t)},statuses:Uye,defaultStatus:"Watching",add:{input:Mgt(),build:(e,t)=>{let r=Number(e.tmdbId);if(!r||!e.id&&!e.mediaType)throw it("tmdbId and mediaType are required");let n=Lgt(e.mediaType||(String(e.id).startsWith("movie:")?"movie":"tv")),i=e.id&&String(e.id).includes(":")?String(e.id):_ye(n,r);return{id:i,row:{id:i,tmdbId:r,mediaType:n,title:String(e.title||""),poster:String(e.poster||""),backdrop:e.backdrop?String(e.backdrop):void 0,year:e.year?String(e.year):void 0,overview:e.overview?String(e.overview):void 0,status:t,adult:e.adult===!0}}}}}));var Fgt=e=>rl(e,"tv_progress","tv_library","mediaId","COALESCE(l.adult, p.adult) = 1"),Ugt=()=>kd("mediaId"),_gt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),Ogt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode,currentTime:t.currentTime,duration:t.duration,completed:t.completed,title:cA(t,"title"),poster:cA(t,"poster"),backdrop:cA(t,"backdrop"),year:cA(t,"year"),overview:cA(t,"overview"),tmdbId:t.tmdbId??null,mediaType:cA(t,"mediaType"),adult:t.adult??null}}),Pgt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),cm=am({db:e=>e.tvDb,write:rh,repo:gu,keyField:"mediaId",byKeyInput:Ugt(),removeInput:Pgt(),normalizeKey:fx,removeOne:(e,t,r)=>r.season===void 0||r.episode===void 0?!1:(gu.deleteEpisode(e,t,Number(r.season),Number(r.episode)),!0),continueRows:(e,t)=>gu.getContinueWatching(e,t),continueSettings:{ignoreAdult:"tvIgnoreAdultContent",listOnly:"tvCwWatchlistOnly"},isAdult:e=>e.adult===1,watchlistStatus:"Watching",adultIds:Fgt}),Pye=At({getByMedia:cm.byKey,latest:ee.input(_gt()).query(async({ctx:e,input:t})=>{let r=fx(t.mediaId),n=parseInt(String(t.season),10),i=parseInt(String(t.episode),10);return Number.isFinite(n)&&Number.isFinite(i)?await gu.getEpisode(e.tvDb,r,n,i)||{currentTime:0,duration:0,completed:0}:await gu.getLatest(e.tvDb,r)||{currentTime:0,duration:0,completed:0}}),save:ee.input(Ogt()).mutation(async({ctx:e,input:t})=>{let r=fx(t.mediaId);if(!r)throw it("mediaId is required");let n=Math.max(Number(t.season)||1,1),i=Math.max(Number(t.episode)||1,1),s=Math.max(Number(t.currentTime)||0,0),o=Math.max(Number(t.duration)||0,0),a=o>0?Math.min(s,o):s,A=o>0&&a>=o*.8?o:a,u=Number(t.completed)===1||o>0&&A>=o*.8?1:0;return await rh(e.tvDb,async c=>{await gu.upsert(c,{mediaId:String(r),season:Math.round(n),episode:Math.round(i),currentTime:A,duration:o,completed:u,title:t.title??null,poster:t.poster??null,backdrop:t.backdrop??null,year:t.year??null,overview:t.overview??null,tmdbId:t.tmdbId!=null?Number(t.tmdbId):null,mediaType:t.mediaType??null,adult:t.adult!=null?Number(t.adult):null}),await gx.touchProgress(c,String(r),{season:Math.round(n),episode:Math.round(i)})}),{success:!0}}),remove:cm.remove,removeMany:cm.removeMany,continueWatching:cm.continue,adultCount:cm.adultCount,purgeAdult:cm.purgeAdult});async function Hgt(e,t,r){let n={...r};if(n.title&&n.imdbId&&n.year)return n;let i=await Lse(e,t);return i&&(n.title||(n.title=i.title||i.name||""),n.year||(n.year=(i.release_date||i.first_air_date||"").split("-")[0]||""),n.imdbId||(n.imdbId=i.external_ids?.imdb_id||i.imdb_id||""),e==="tv"&&i.number_of_seasons&&(n.totalSeasons=String(i.number_of_seasons))),n}function J5(e,t){return{id:e.id,title:e.title||e.name||"",year:(e.release_date||e.first_air_date||"").split("-")[0],type:t,image:e.poster_path?`${Xl}/w500${e.poster_path}`:"",backdrop:e.backdrop_path?`${Xl}/w780${e.backdrop_path}`:"",overview:e.overview||"",vote_average:e.vote_average||0,adult:e.adult===!0,genre_ids:e.genre_ids||[]}}var Ggt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=Ri(t));let i=le(t,"type");i!==void 0&&(r.type=i);let s=le(t,"genre");s!==void 0&&(r.genre=s);let o=le(t,"year");o!==void 0&&(r.year=o);let a=le(t,"sortBy");return a!==void 0&&(r.sortBy=a),r}),Ygt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"mediaType");n!==void 0&&(r.mediaType=n);let i=le(t,"timeWindow");return i!==void 0&&(r.timeWindow=i),t.page!==void 0&&(r.page=Ri(t)),r}),Vgt=()=>pe(e=>{let t=ye(e);return{type:gt(t,"type"),id:uA(t,"id")}}),qgt=()=>pe(e=>{let t=ye(e);return{id:uA(t,"id"),season:uA(t,"season")}}),Wgt=()=>pe(e=>{let t=ye(e),r={type:gt(t,"type"),tmdbId:uA(t,"tmdbId")},n=le(t,"season");n!==void 0&&(r.season=n);let i=le(t,"episode");return i!==void 0&&(r.episode=i),r}),Jgt=()=>pe(e=>{let t=ye(e),r={provider:gt(t,"provider"),type:gt(t,"type"),tmdbId:uA(t,"tmdbId")};t.season!==void 0&&(r.season=$y(t,"season",1)),t.episode!==void 0&&(r.episode=$y(t,"episode",1));let n=le(t,"server");n!==void 0&&(r.server=n);let i=le(t,"title");i!==void 0&&(r.title=i);let s=le(t,"year");s!==void 0&&(r.year=s);let o=le(t,"imdbId");o!==void 0&&(r.imdbId=o);let a=le(t,"totalSeasons");return a!==void 0&&(r.totalSeasons=a),r}),Hye=At({search:ee.input(Ggt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.type||"multi",s=t.genre||"",o=t.year||"",a=t.sortBy||"popularity.desc",A=`tv-search-${r.toLowerCase()}-${n}-${i}-${s}-${o}-${a}`,u=e.apiCache.get(A);if(u)return u;try{let c=await Rse({query:r,page:n,type:i,genre:s,year:o,sortBy:a}),l;i==="tv"||i==="movie"?l=(c.results||[]).map(h=>J5(h,i)):l=(c.results||[]).filter(h=>h.media_type!=="person").map(h=>J5(h,h.media_type||"tv"));let d={results:l,total_results:c.total_results||0,total_pages:c.total_pages||0,page:c.page||n};return e.apiCache.set(A,d,1800),d}catch(c){throw c instanceof nt?c:yr(c.message)}}),trending:ee.input(Ygt()).query(async({ctx:e,input:t})=>{let r=t.mediaType||"all",n=t.timeWindow||"week",i=t.page||1,s=`tv-trending-${r}-${n}-${i}`,o=e.apiCache.get(s);if(o)return o;try{let a=await xse(r,n,i),u={results:(a.results||[]).filter(c=>c.media_type!=="person").map(c=>J5(c,c.media_type||"tv")),total_results:a.total_results||0,total_pages:a.total_pages||0,page:a.page||i};return e.apiCache.set(s,u,3600),u}catch(a){throw a instanceof nt?a:yr(a.message)}}),details:ee.input(Vgt()).query(async({input:e})=>{let t=e.type,r=e.id;try{let n=await vse(t,r),i={id:n.id,imdb_id:n.external_ids?.imdb_id||n.imdb_id||null,title:n.title||n.name,overview:n.overview,vote_average:n.vote_average,year:(n.release_date||n.first_air_date||"").split("-")[0],poster:n.poster_path?`${Xl}/w500${n.poster_path}`:"",backdrop:n.backdrop_path?`${Xl}/original${n.backdrop_path}`:"",adult:n.adult===!0};return t==="tv"&&(i.seasons=(n.seasons||[]).filter(s=>s.season_number>0).map(s=>({season_number:s.season_number,episode_count:s.episode_count})),i.number_of_seasons=n.number_of_seasons),i}catch(n){throw n instanceof nt?n:yr(n.message)}}),episodes:ee.input(qgt()).query(async({input:e})=>{let t=e.id,r=e.season;try{return{episodes:(await kse(t,r)).map(i=>({episode_number:i.episode_number,name:i.name,vote_average:i.vote_average,overview:i.overview,still_path:i.still_path}))}}catch(n){throw n instanceof nt?n:yr(n.message)}}),subtitles:ee.input(Wgt()).query(async({ctx:e,input:t})=>{let r=t.type,n=t.tmdbId,i=parseInt(n,10);if(!i)return{subtitles:[]};let s=r==="movie"?"movie":"tv",o=t.season||"1",a=t.episode||"1",A=s==="tv"?`tv-subs-${i}-${o}-${a}`:`tv-subs-${i}-movie`,u=e.apiCache.get(A);if(u)return u;try{let c=s==="tv"?`https://subtitles.vidy.st/search?id=${i}&season=${encodeURIComponent(o)}&episode=${encodeURIComponent(a)}`:`https://subtitles.vidy.st/search?id=${i}`,l=await Sr(c,{headers:{"User-Agent":"Mozilla/5.0"}},{timeoutMs:1e4});if(!l.ok)return{subtitles:[]};let d=await Vt(l),f={subtitles:(Array.isArray(d)?d:[]).filter(g=>typeof g.url=="string"&&g.url.startsWith("https://")).map(g=>({language:String(g.language||"en"),label:String(g.display||g.language||"Unknown"),url:String(g.url),trusted:g.isTrusted===!0,hi:g.isHearingImpaired===!0,downloads:Number(g.downloadCount)||0,media:String(g.media||g.release||"")})).sort((g,p)=>{let m=g.language.toLowerCase().startsWith("en")?0:1,I=p.language.toLowerCase().startsWith("en")?0:1;return m!==I?m-I:g.trusted!==p.trusted?g.trusted?-1:1:p.downloads-g.downloads}).slice(0,50)};return e.apiCache.set(A,f,3600),f}catch(c){return U.warn({err:c,mediaType:s,tmdbId:n},"Subtitle fetch failed"),{subtitles:[]}}}),sources:ee.input(Jgt()).query(async({ctx:e,input:t})=>{let r=t.provider,n=t.type,i=t.tmdbId,s=n==="movie"?"movie":"tv",o=parseInt(i,10);if(!o)throw it("Bad tmdb id");let a=e.getTvProvider(String(r).toLowerCase());if(!a||typeof a.getSources!="function")throw it(`Unknown TV provider ${r}`);let A=t.season||1,u=t.episode||1,c=t.server,l=await Hgt(s,o,{title:t.title||"",year:t.year||"",imdbId:t.imdbId||"",totalSeasons:t.totalSeasons||"1"}),d=tx({tmdbId:o,type:s,season:A,episode:u,title:l.title,year:l.year,imdbId:l.imdbId,totalSeasons:parseInt(l.totalSeasons,10)||1});try{let h=await a.getSources(d,c);return!h||!Array.isArray(h.sources)||h.sources.length===0?{provider:a.name,server:h?.server||c,sources:[],audioTracks:[],valid:!1,error:"No sources found"}:{provider:a.name,server:h.server||c,servers:h.servers,embedUrl:h.embedUrl,sources:h.sources,audioTracks:h.audioTracks||[],subtitles:h.subtitles||[],referer:h.referer||"",valid:!0}}catch(h){throw yr(h.message)}})});async function jn(e,t,r,n,i){let s=e.apiCache.get(t);if(s)return s;let o=await n();return(!i||i(o))&&(r!==void 0?e.apiCache.set(t,o,r):e.apiCache.set(t,o)),o}var Gye=["safe"];function Yye(e){let t=e.mature==="1",r=String(e.rating||"safe").split(",").map(i=>i.trim().toLowerCase()).filter(i=>["safe","suggestive","erotica","pornographic"].includes(i));if(!t)return Gye;let n=[...new Set(r)];return n.length>0?n:Gye}function $5(e,t){return e.getMangaProvider(t.toLowerCase())}async function Vye(e,t,r){let n=t?[t]:e.getCatalog().filter(i=>i.kind==="manga"&&i.loaded).map(i=>i.id);for(let i of n){let s=$5(e,i);if(!s)continue;let o=await s.search({query:r.query,page:r.page,limit:r.limit,sort:r.sort,status:r.status,type:r.type,ratings:r.ratings}),a=o?.items??[];if(a.length>0||t)return{items:a,hasNext:o?.hasNext??!1,provider:i}}return{items:[],hasNext:!1,provider:t||n[0]||""}}async function j5(e,t,r,n){let i=await jn(e,t,r,n,s=>{let o=s.status??200;return o>=200&&o<400});if(i.status!==void 0&&i.status!==200){let s=i.body?.error||"Request failed";throw i.status===400?it(s):i.status===404?Mc(s):yr(s)}return i.body}var jgt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","q","sort","status","type","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,24,50)),r}),$gt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","id","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return r}),Kgt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"id");return i!==void 0&&(r.id=i),r}),qye=At({trending:ee.query(async({ctx:e})=>{let t="route-manga-trending",r=e.apiCache.get(t);if(r)return r;let n=await Vye(e,"",{query:"",page:1,limit:6,sort:"followed",status:"",type:"",ratings:["safe","suggestive"]}),i=n.items.map(s=>({id:s.id,provider:n.provider,title:s.title,description:typeof s.description=="string"?s.description:"",tags:Array.isArray(s.genres)?s.genres:[],year:typeof s.year=="number"?s.year:null,status:typeof s.status=="string"?s.status:null,cover:s.cover??""}));return e.apiCache.set(t,i,600),i}),search:ee.input(jgt()).query(async({ctx:e,input:t})=>{let r=t.provider||"",n=t.q||"",i=t.page||1;return j5(e,`route-manga-search-${r}-${n}-${i}-${t.sort||""}-${t.status||""}-${t.type||""}-${t.rating||""}-${t.mature||""}`,300,async()=>{try{let s=Yye({rating:t.rating,mature:t.mature}),o=t.type||"",a=o==="doujinshi"&&t.mature!=="1"?"":o,A=await Vye(e,r,{query:n,page:i,limit:t.limit||24,sort:t.sort||"popular",status:t.status||"",type:a,ratings:s});return{body:{...A,items:A.items??[]}}}catch(s){return U.error({err:s},"[Manga] search failed"),{body:{items:[],hasNext:!1,provider:r}}}})}),info:ee.input($gt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||""),i=String(t.rating||""),s=String(t.mature||"");return j5(e,`route-manga-info-${r}-${n}-${i}-${s}`,600,async()=>{try{if(!n)return{status:400,body:{error:"Missing id"}};let o=await $5(e,r)?.getDetail(n,Yye({rating:i,mature:s}));return o?{body:o}:{status:404,body:{error:"Not found"}}}catch(o){return U.error({err:o},"[Manga] info failed"),{status:500,body:{error:"Failed to load manga"}}}})}),pages:ee.input(Kgt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||"");return j5(e,`route-manga-pages-${r}-${n}`,300,async()=>{try{return n?{body:{pages:await $5(e,r)?.getPages(n)??[]}}:{status:400,body:{error:"Missing id"}}}catch(i){return U.error({err:i},"[Manga] pages failed"),{body:{pages:[]}}}})})});var Xgt=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=parseInt(String(t.page),10)||1);let i=le(t,"sort");i!==void 0&&(r.sort=i);let s=le(t,"rating");return s!==void 0&&(r.rating=s),r}),zgt=()=>pe(e=>({rj:gt(ye(e),"rj")})),Wye=At({browse:ee.input(Xgt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.sort||"",s=t.rating||"";return jn(e,`route-asmr-browse-${r}-${n}-${i}-${s}-${i==="random"?Date.now():""}`,300,async()=>{try{let o=e.getJasmr();return o?await o.browse({query:r,page:n,sort:i,rating:s}):{shows:[],hasNext:!1}}catch(o){if(o.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:o},"[Asmr] browse failed"),{shows:[],hasNext:!1}}})}),work:ee.input(zgt()).query(async({ctx:e,input:t})=>{let r=t.rj;return jn(e,`route-asmr-work-${r}`,1800,async()=>{try{let n=e.getJasmr();if(!n)return{rjCode:r,description:"",tracks:[],images:[],chapters:[]};let i=String(r).trim().toUpperCase(),s=await n.getEpisodes(i),[o,a,A]=await Promise.all([n.getStreamUrls(i,"1"),n.getImages(i),n.getChapters(i)]);return{rjCode:i,description:s?.description||"",tracks:o?.[0]?.links||[],images:a,chapters:A}}catch(n){if(n.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:n,rj:r},"[Asmr] work fetch failed"),{rjCode:r,description:"",tracks:[],images:[],chapters:[]}}})})});var K5="tracker_anilist_token",eQ="tracker_anilist_sync_state";function X5(e){if(!(!e||e<=0))return new Date(e*1e3).toISOString().slice(0,19).replace("T"," ")}function Zgt(e){return["Watching","Completed","On-Hold","Dropped","Planned"].includes(e)?e:void 0}async function Jye(e,t){return(await hi(e,"SELECT COUNT(DISTINCT episodeNumber) as total FROM watched_episodes WHERE showId = ?",[t]))?.total??0}async function z5(e){let r=(await xe.getByKey(e,K5))?.value;if(!r)throw new Error("AniList is not connected. Please log in first.");let n=new ma(r),i=await n.getViewer(),s=await n.fetchUserAnimeList(i.id),o=await _t.getAll(e),a=await Td(e,eQ),A=new Map;for(let B of s)A.set(B.mediaId,B);let u=new Map;for(let B of o){let w=(await ct.getById(e,B.id))?.anilistId;w==null||!Number.isFinite(w)||String(w)!==String(B.id)||u.has(w)||u.set(w,B)}let c=$R(u.keys(),A.keys(),a),l={pushed:0,pulled:0,merged:0,unchanged:0,errors:[]},d=[],h=[],f=[],g={},p=[],m=[],I=[],C=Math.floor(Date.now()/1e3);for(let B of c){let Q=u.get(B),w=A.get(B),R=String(B);try{if(Q&&!w){if(a[R]&&s.length>0){p.push(R),g[R]=void 0,l.pulled++;continue}let N=await Jye(e,R);m.push({mediaId:B,status:Zgt(Q.status),progress:N}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.pushed++;continue}if(!Q&&w){if(a[R]){if(w.entryId){I.push({showId:R,entryId:w.entryId}),g[R]=void 0,l.pushed++;continue}g[R]=void 0,l.pushed++;continue}U.debug({mediaId:B,remoteStatus:w.status},"[AniList Sync] Remote only -> pulling to local");let N=w.title.english||w.title.romaji||`Anime #${B}`;d.push({id:R,name:N,thumbnail:w.coverImage??"",status:w.status,nativeName:w.title.native??"",englishName:w.title.english??"",type:"TV"}),h.push({id:R,name:N,thumbnail:w.coverImage,nativeName:w.title.native,englishName:w.title.english,episodeCount:w.totalEpisodes,anilistId:B,episodeDuration:w.episodeDuration}),w.progress>0&&f.push({showId:R,from:1,to:w.progress,updatedAt:w.updatedAt}),g[R]={lastSyncedAt:C,remoteUpdatedAt:w.updatedAt},l.pulled++;continue}if(!Q&&!w&&a[R]){g[R]=void 0;continue}if(Q&&w){let N=await Jye(e,R),T=a[R]?.lastSyncedAt??0,Y=w.updatedAt||0,P=Math.max(N,w.progress),O=N>w.progress,W=w.progress>N,{status:oe,pull:ue}=jR(Q.status,w.status,Y,T),Ce=w.status!==Q.status;O||!ue&&Ce?(m.push({mediaId:B,status:oe,progress:P}),oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.merged++):ue||W?(oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:Y},l.merged++):l.unchanged++}}catch(N){let T=N instanceof Error?N.message:String(N);U.warn({err:N,mediaId:B},"[AniList Sync] Entry failed"),l.errors.push(`${Q?.name??`Media ${B}`}: ${T}`)}}return(m.length>0||I.length>0||p.length>0)&&KR({totalDeletes:p.length+I.length,localItemCount:o.length,fetched:s.length,message:`AniList sync would delete ${p.length+I.length} shows but only ${s.length} were fetched. Aborting to protect your library - if you really removed that many shows on AniList, delete them locally first and sync again.`}),await XR(n,m,I),(d.length>0||h.length>0||f.length>0||p.length>0||Object.keys(g).length>0)&&await tt(e,async B=>{for(let w of d)await _t.upsert(B,w);for(let w of h)await ct.upsert(B,w);for(let w of f)for(let R=w.from;R<=w.to;R++)await Qr.insertIfMissing(B,{showId:w.showId,episodeNumber:String(R),watchedAt:X5(w.updatedAt)});for(let w of p)await _t.delete(B,w),await Qr.deleteByShow(B,w),await Zr.deleteByShow(B,w);let Q={...a};for(let[w,R]of Object.entries(g))R===void 0?delete Q[w]:Q[w]=R;await xe.upsert(B,eQ,JSON.stringify(Q))}),l}async function Z5(e,t,r=!1){let i=(await xe.getByKey(e,K5))?.value,s=new ma(i),o;if(i){let u=await s.getViewer();o=await s.fetchUserAnimeList(u.id)}else o=await s.fetchUserAnimeList(t);if(o.length===0)return 0;let a=Math.floor(Date.now()/1e3),A=await Td(e,eQ);return await tt(e,async u=>{r&&await xe.clearWatchlist(u);for(let c of o){let l=String(c.mediaId),d=c.title.english||c.title.romaji||`Anime #${c.mediaId}`;if(await _t.upsert(u,{id:l,name:d,thumbnail:c.coverImage??"",status:c.status,nativeName:c.title.native??"",englishName:c.title.english??"",type:"TV"}),await ct.upsert(u,{id:l,name:d,thumbnail:c.coverImage,nativeName:c.title.native,englishName:c.title.english,episodeCount:c.totalEpisodes,anilistId:c.mediaId}),c.progress>0)for(let h=1;h<=c.progress;h++)await Qr.insertIfMissing(u,{showId:l,episodeNumber:String(h),watchedAt:X5(c.updatedAt)});A[l]={lastSyncedAt:a,remoteUpdatedAt:c.updatedAt}}await xe.upsert(u,eQ,JSON.stringify(A))}),o.length}function jye(e){switch(e){case 1:return"Watching";case 2:return"Completed";case 3:return"On-Hold";case 4:return"Dropped";case 6:return"Planned";default:return null}}async function e0t(e){let t=await ys(e);if(t)return t.id;if(qi())try{let r=await ra({query:e,page:1,perPage:5});if(r.length>0)return r[0].id>0?r[0].id:null}catch{}return null}async function eG(e,t,r={}){let{erase:n=!1,useOfflineDb:i=!0,skipFallback:s=!1}=r,o=await mP(t);if(o.length===0)return 0;let a=[],A=[],u=[],c=[];for(let l of o){let d=jye(l.status);if(!d)continue;let h=i?pn.getByMalId(l.malId):null;if(h){let f=String(h.anilistId),g=h.title||l.titleEnglish||l.title||`MAL #${l.malId}`;a.push({id:f,name:g,thumbnail:h.thumbnail??l.imageUrl??void 0,status:d,englishName:l.titleEnglish??void 0,type:h.type??l.type??void 0}),(h.thumbnail||h.type||h.genres)&&A.push({id:f,thumbnail:h.thumbnail,type:h.type,genres:h.genres}),l.watchedEpisodes>0&&u.push({showId:f,progress:l.watchedEpisodes})}else c.push(l)}if(c.length>0&&!s)for(let d=0;d<c.length;d+=5){let h=c.slice(d,d+5);(await Promise.allSettled(h.map(async g=>{let p=await cc(g.malId).catch(()=>null);if(p?.anilistId)return p;let m=g.titleEnglish||g.title;if(!m)return null;let I=await e0t(m);return I?bi(String(I)).catch(()=>null):null}))).forEach((g,p)=>{if(g.status!=="fulfilled"||!g.value)return;let m=g.value,I=h[p],C=jye(I.status);if(!C)return;let B=m.anilistId?String(m.anilistId):m._id,Q=m.names?.english||m.names?.romaji||I.titleEnglish||I.title||`MAL #${I.malId}`;a.push({id:B,name:Q,thumbnail:m.thumbnail||I.imageUrl||void 0,status:C,englishName:I.titleEnglish??void 0,type:m.type??I.type??"TV"}),(m.thumbnail||m.type)&&A.push({id:B,thumbnail:m.thumbnail,type:m.type}),I.watchedEpisodes>0&&u.push({showId:B,progress:I.watchedEpisodes})})}return(a.length>0||n)&&await tt(e,async l=>{n&&await xe.clearWatchlist(l);for(let d of a)await _t.upsert(l,{id:d.id,name:d.name,thumbnail:d.thumbnail??"",status:d.status,nativeName:"",englishName:d.englishName??"",type:d.type??"TV"});for(let d of A)(d.thumbnail||d.type||d.genres)&&await ct.upsert(l,{id:d.id,thumbnail:d.thumbnail,type:d.type,genres:d.genres});for(let d of u)for(let h=1;h<=d.progress;h++)await Qr.insertIfMissing(l,{showId:d.showId,episodeNumber:String(h)})}),a.length}var tG="tracker_anilist_token",rG="tracker_anilist_user";function tQ(e){return e==null?{}:ye(e)}var t0t=()=>pe(e=>{let t=tQ(e);return{token:t.token,code:t.code,redirectUri:t.redirectUri}}),r0t=()=>pe(e=>({provider:tQ(e).provider})),nG=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase}}),n0t=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase,useOfflineDb:t.useOfflineDb,skipFallback:t.skipFallback}}),i0t=()=>pe(e=>({direction:tQ(e).direction}));function $ye(e){return e.includes("private")||e.includes("not found")?Mc(e):e.includes("blocked")||e.includes("HTTP 429")?PBe(e):yr(e)}var Kye=At({status:ee.query(async({ctx:e})=>{try{let t=await xe.getByKey(e.db,tG),r=await xe.getByKey(e.db,rG),n=null;if(r?.value)try{n=JSON.parse(r.value)}catch(i){U.warn({err:i},"The stored tracker user is not valid json"),n=null}return{anilist:{connected:!!t?.value,user:n}}}catch{throw yr("Failed to read tracker status")}}),anilistAuth:ee.input(t0t()).mutation(async({ctx:e,input:t})=>{let r=typeof t.token=="string"?t.token.trim():"";if(!r)throw it("Access token is required");try{let i=await new ma(r).getViewer();return await tt(e.db,async s=>{await xe.upsert(s,tG,r),await xe.upsert(s,rG,JSON.stringify(i))}),{success:!0,user:i}}catch(n){throw GBe(n instanceof Error?n.message:"Authentication failed")}}),anilistDisconnect:ee.mutation(async({ctx:e})=>{try{return await tt(e.db,async t=>{await xe.upsert(t,tG,""),await xe.upsert(t,rG,"")}),{success:!0}}catch{throw yr("Failed to disconnect")}}),sync:ee.input(r0t()).mutation(async({ctx:e,input:t})=>{let{provider:r="anilist"}=t;if(r!=="anilist")throw it(`Provider "${r}" is not supported yet`);try{return{success:!0,summary:await z5(e.db)}}catch(n){throw yr(n instanceof Error?n.message:"Sync failed")}}),anilistImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{return{success:!0,count:await Z5(e.db,r.trim(),n===!0)}}catch(i){throw yr(i instanceof Error?i.message:"Import failed")}}),malImport:ee.input(n0t()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n,useOfflineDb:i,skipFallback:s}=t;if(!r||typeof r!="string")throw it("MAL username is required");try{return{success:!0,count:await eG(e.db,r.trim(),{erase:n===!0,useOfflineDb:i!==!1,skipFallback:s===!0})}}catch(o){throw $ye(o instanceof Error?o.message:"Import failed")}}),mangaSync:ee.input(i0t()).mutation(async({ctx:e,input:t})=>{let{direction:r}=t;try{let n=e.mangaDb;if(!n||n.isClosedCheck())throw vd("Manga database is not ready");let i=r==="pull-only"?"pull-only":"two-way",s=await p5(e.db,n,{direction:i});return{success:!0,summary:s.summary,details:s.details,direction:i}}catch(n){throw n instanceof nt?n:yr(n instanceof Error?n.message:"Manga sync failed")}}),mangaImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,count:await m5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:yr(i instanceof Error?i.message:"Import failed")}}),mangaMalImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,...await I5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:$ye(i instanceof Error?i.message:"Import failed")}})});var Ms={getCoreStats:async e=>(await te(e).all(y`
894
+ ${y.raw(r)}`)}};function Lgt(e){return String(e).toLowerCase()==="movie"?"movie":"tv"}var Mgt=()=>pe(e=>{let t=ye(e);return{tmdbId:t.tmdbId,mediaType:t.mediaType,id:t.id,title:t.title,poster:t.poster,backdrop:t.backdrop,year:t.year,overview:t.overview,status:t.status,adult:t.adult}}),Oye=At(om({db:e=>e.tvDb,write:rh,repo:gx,progress:{deleteByKey:(e,t)=>gu.deleteByKey(e,t),deleteMany:(e,t)=>gu.deleteMany(e,t)},statuses:Uye,defaultStatus:"Watching",add:{input:Mgt(),build:(e,t)=>{let r=Number(e.tmdbId);if(!r||!e.id&&!e.mediaType)throw it("tmdbId and mediaType are required");let n=Lgt(e.mediaType||(String(e.id).startsWith("movie:")?"movie":"tv")),i=e.id&&String(e.id).includes(":")?String(e.id):_ye(n,r);return{id:i,row:{id:i,tmdbId:r,mediaType:n,title:String(e.title||""),poster:String(e.poster||""),backdrop:e.backdrop?String(e.backdrop):void 0,year:e.year?String(e.year):void 0,overview:e.overview?String(e.overview):void 0,status:t,adult:e.adult===!0}}}}}));var Fgt=e=>rl(e,"tv_progress","tv_library","mediaId","COALESCE(l.adult, p.adult) = 1"),Ugt=()=>kd("mediaId"),_gt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),Ogt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode,currentTime:t.currentTime,duration:t.duration,completed:t.completed,title:cA(t,"title"),poster:cA(t,"poster"),backdrop:cA(t,"backdrop"),year:cA(t,"year"),overview:cA(t,"overview"),tmdbId:t.tmdbId??null,mediaType:cA(t,"mediaType"),adult:t.adult??null}}),Pgt=()=>pe(e=>{let t=ye(e);return{mediaId:gt(t,"mediaId"),season:t.season,episode:t.episode}}),cm=am({db:e=>e.tvDb,write:rh,repo:gu,keyField:"mediaId",byKeyInput:Ugt(),removeInput:Pgt(),normalizeKey:fx,removeOne:(e,t,r)=>r.season===void 0||r.episode===void 0?!1:(gu.deleteEpisode(e,t,Number(r.season),Number(r.episode)),!0),continueRows:(e,t)=>gu.getContinueWatching(e,t),continueSettings:{ignoreAdult:"tvIgnoreAdultContent",listOnly:"tvCwWatchlistOnly"},isAdult:e=>e.adult===1,watchlistStatus:"Watching",adultIds:Fgt}),Pye=At({getByMedia:cm.byKey,latest:ee.input(_gt()).query(async({ctx:e,input:t})=>{let r=fx(t.mediaId),n=parseInt(String(t.season),10),i=parseInt(String(t.episode),10);return Number.isFinite(n)&&Number.isFinite(i)?await gu.getEpisode(e.tvDb,r,n,i)||{currentTime:0,duration:0,completed:0}:await gu.getLatest(e.tvDb,r)||{currentTime:0,duration:0,completed:0}}),save:ee.input(Ogt()).mutation(async({ctx:e,input:t})=>{let r=fx(t.mediaId);if(!r)throw it("mediaId is required");let n=Math.max(Number(t.season)||1,1),i=Math.max(Number(t.episode)||1,1),s=Math.max(Number(t.currentTime)||0,0),o=Math.max(Number(t.duration)||0,0),a=o>0?Math.min(s,o):s,A=Number(t.completed)===1||o>0&&a>=o*.8?1:0;return await rh(e.tvDb,async u=>{await gu.upsert(u,{mediaId:String(r),season:Math.round(n),episode:Math.round(i),currentTime:a,duration:o,completed:A,title:t.title??null,poster:t.poster??null,backdrop:t.backdrop??null,year:t.year??null,overview:t.overview??null,tmdbId:t.tmdbId!=null?Number(t.tmdbId):null,mediaType:t.mediaType??null,adult:t.adult!=null?Number(t.adult):null}),await gx.touchProgress(u,String(r),{season:Math.round(n),episode:Math.round(i)})}),{success:!0}}),remove:cm.remove,removeMany:cm.removeMany,continueWatching:cm.continue,adultCount:cm.adultCount,purgeAdult:cm.purgeAdult});async function Hgt(e,t,r){let n={...r};if(n.title&&n.imdbId&&n.year)return n;let i=await Lse(e,t);return i&&(n.title||(n.title=i.title||i.name||""),n.year||(n.year=(i.release_date||i.first_air_date||"").split("-")[0]||""),n.imdbId||(n.imdbId=i.external_ids?.imdb_id||i.imdb_id||""),e==="tv"&&i.number_of_seasons&&(n.totalSeasons=String(i.number_of_seasons))),n}function J5(e,t){return{id:e.id,title:e.title||e.name||"",year:(e.release_date||e.first_air_date||"").split("-")[0],type:t,image:e.poster_path?`${Xl}/w500${e.poster_path}`:"",backdrop:e.backdrop_path?`${Xl}/w780${e.backdrop_path}`:"",overview:e.overview||"",vote_average:e.vote_average||0,adult:e.adult===!0,genre_ids:e.genre_ids||[]}}var Ggt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=Ri(t));let i=le(t,"type");i!==void 0&&(r.type=i);let s=le(t,"genre");s!==void 0&&(r.genre=s);let o=le(t,"year");o!==void 0&&(r.year=o);let a=le(t,"sortBy");return a!==void 0&&(r.sortBy=a),r}),Ygt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"mediaType");n!==void 0&&(r.mediaType=n);let i=le(t,"timeWindow");return i!==void 0&&(r.timeWindow=i),t.page!==void 0&&(r.page=Ri(t)),r}),Vgt=()=>pe(e=>{let t=ye(e);return{type:gt(t,"type"),id:uA(t,"id")}}),qgt=()=>pe(e=>{let t=ye(e);return{id:uA(t,"id"),season:uA(t,"season")}}),Wgt=()=>pe(e=>{let t=ye(e),r={type:gt(t,"type"),tmdbId:uA(t,"tmdbId")},n=le(t,"season");n!==void 0&&(r.season=n);let i=le(t,"episode");return i!==void 0&&(r.episode=i),r}),Jgt=()=>pe(e=>{let t=ye(e),r={provider:gt(t,"provider"),type:gt(t,"type"),tmdbId:uA(t,"tmdbId")};t.season!==void 0&&(r.season=$y(t,"season",1)),t.episode!==void 0&&(r.episode=$y(t,"episode",1));let n=le(t,"server");n!==void 0&&(r.server=n);let i=le(t,"title");i!==void 0&&(r.title=i);let s=le(t,"year");s!==void 0&&(r.year=s);let o=le(t,"imdbId");o!==void 0&&(r.imdbId=o);let a=le(t,"totalSeasons");return a!==void 0&&(r.totalSeasons=a),r}),Hye=At({search:ee.input(Ggt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.type||"multi",s=t.genre||"",o=t.year||"",a=t.sortBy||"popularity.desc",A=`tv-search-${r.toLowerCase()}-${n}-${i}-${s}-${o}-${a}`,u=e.apiCache.get(A);if(u)return u;try{let c=await Rse({query:r,page:n,type:i,genre:s,year:o,sortBy:a}),l;i==="tv"||i==="movie"?l=(c.results||[]).map(h=>J5(h,i)):l=(c.results||[]).filter(h=>h.media_type!=="person").map(h=>J5(h,h.media_type||"tv"));let d={results:l,total_results:c.total_results||0,total_pages:c.total_pages||0,page:c.page||n};return e.apiCache.set(A,d,1800),d}catch(c){throw c instanceof nt?c:yr(c.message)}}),trending:ee.input(Ygt()).query(async({ctx:e,input:t})=>{let r=t.mediaType||"all",n=t.timeWindow||"week",i=t.page||1,s=`tv-trending-${r}-${n}-${i}`,o=e.apiCache.get(s);if(o)return o;try{let a=await xse(r,n,i),u={results:(a.results||[]).filter(c=>c.media_type!=="person").map(c=>J5(c,c.media_type||"tv")),total_results:a.total_results||0,total_pages:a.total_pages||0,page:a.page||i};return e.apiCache.set(s,u,3600),u}catch(a){throw a instanceof nt?a:yr(a.message)}}),details:ee.input(Vgt()).query(async({input:e})=>{let t=e.type,r=e.id;try{let n=await vse(t,r),i={id:n.id,imdb_id:n.external_ids?.imdb_id||n.imdb_id||null,title:n.title||n.name,overview:n.overview,vote_average:n.vote_average,year:(n.release_date||n.first_air_date||"").split("-")[0],poster:n.poster_path?`${Xl}/w500${n.poster_path}`:"",backdrop:n.backdrop_path?`${Xl}/original${n.backdrop_path}`:"",adult:n.adult===!0};return t==="tv"&&(i.seasons=(n.seasons||[]).filter(s=>s.season_number>0).map(s=>({season_number:s.season_number,episode_count:s.episode_count})),i.number_of_seasons=n.number_of_seasons),i}catch(n){throw n instanceof nt?n:yr(n.message)}}),episodes:ee.input(qgt()).query(async({input:e})=>{let t=e.id,r=e.season;try{return{episodes:(await kse(t,r)).map(i=>({episode_number:i.episode_number,name:i.name,vote_average:i.vote_average,overview:i.overview,still_path:i.still_path}))}}catch(n){throw n instanceof nt?n:yr(n.message)}}),subtitles:ee.input(Wgt()).query(async({ctx:e,input:t})=>{let r=t.type,n=t.tmdbId,i=parseInt(n,10);if(!i)return{subtitles:[]};let s=r==="movie"?"movie":"tv",o=t.season||"1",a=t.episode||"1",A=s==="tv"?`tv-subs-${i}-${o}-${a}`:`tv-subs-${i}-movie`,u=e.apiCache.get(A);if(u)return u;try{let c=s==="tv"?`https://subtitles.vidy.st/search?id=${i}&season=${encodeURIComponent(o)}&episode=${encodeURIComponent(a)}`:`https://subtitles.vidy.st/search?id=${i}`,l=await Sr(c,{headers:{"User-Agent":"Mozilla/5.0"}},{timeoutMs:1e4});if(!l.ok)return{subtitles:[]};let d=await Vt(l),f={subtitles:(Array.isArray(d)?d:[]).filter(g=>typeof g.url=="string"&&g.url.startsWith("https://")).map(g=>({language:String(g.language||"en"),label:String(g.display||g.language||"Unknown"),url:String(g.url),trusted:g.isTrusted===!0,hi:g.isHearingImpaired===!0,downloads:Number(g.downloadCount)||0,media:String(g.media||g.release||"")})).sort((g,p)=>{let m=g.language.toLowerCase().startsWith("en")?0:1,I=p.language.toLowerCase().startsWith("en")?0:1;return m!==I?m-I:g.trusted!==p.trusted?g.trusted?-1:1:p.downloads-g.downloads}).slice(0,50)};return e.apiCache.set(A,f,3600),f}catch(c){return U.warn({err:c,mediaType:s,tmdbId:n},"Subtitle fetch failed"),{subtitles:[]}}}),sources:ee.input(Jgt()).query(async({ctx:e,input:t})=>{let r=t.provider,n=t.type,i=t.tmdbId,s=n==="movie"?"movie":"tv",o=parseInt(i,10);if(!o)throw it("Bad tmdb id");let a=e.getTvProvider(String(r).toLowerCase());if(!a||typeof a.getSources!="function")throw it(`Unknown TV provider ${r}`);let A=t.season||1,u=t.episode||1,c=t.server,l=await Hgt(s,o,{title:t.title||"",year:t.year||"",imdbId:t.imdbId||"",totalSeasons:t.totalSeasons||"1"}),d=tx({tmdbId:o,type:s,season:A,episode:u,title:l.title,year:l.year,imdbId:l.imdbId,totalSeasons:parseInt(l.totalSeasons,10)||1});try{let h=await a.getSources(d,c);return!h||!Array.isArray(h.sources)||h.sources.length===0?{provider:a.name,server:h?.server||c,sources:[],audioTracks:[],valid:!1,error:"No sources found"}:{provider:a.name,server:h.server||c,servers:h.servers,embedUrl:h.embedUrl,sources:h.sources,audioTracks:h.audioTracks||[],subtitles:h.subtitles||[],referer:h.referer||"",valid:!0}}catch(h){throw yr(h.message)}})});async function jn(e,t,r,n,i){let s=e.apiCache.get(t);if(s)return s;let o=await n();return(!i||i(o))&&(r!==void 0?e.apiCache.set(t,o,r):e.apiCache.set(t,o)),o}var Gye=["safe"];function Yye(e){let t=e.mature==="1",r=String(e.rating||"safe").split(",").map(i=>i.trim().toLowerCase()).filter(i=>["safe","suggestive","erotica","pornographic"].includes(i));if(!t)return Gye;let n=[...new Set(r)];return n.length>0?n:Gye}function $5(e,t){return e.getMangaProvider(t.toLowerCase())}async function Vye(e,t,r){let n=t?[t]:e.getCatalog().filter(i=>i.kind==="manga"&&i.loaded).map(i=>i.id);for(let i of n){let s=$5(e,i);if(!s)continue;let o=await s.search({query:r.query,page:r.page,limit:r.limit,sort:r.sort,status:r.status,type:r.type,ratings:r.ratings}),a=o?.items??[];if(a.length>0||t)return{items:a,hasNext:o?.hasNext??!1,provider:i}}return{items:[],hasNext:!1,provider:t||n[0]||""}}async function j5(e,t,r,n){let i=await jn(e,t,r,n,s=>{let o=s.status??200;return o>=200&&o<400});if(i.status!==void 0&&i.status!==200){let s=i.body?.error||"Request failed";throw i.status===400?it(s):i.status===404?Mc(s):yr(s)}return i.body}var jgt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","q","sort","status","type","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,24,50)),r}),$gt=()=>pe(e=>{let t=ye(e),r={};for(let n of["provider","id","rating","mature"]){let i=le(t,n);i!==void 0&&(r[n]=i)}return r}),Kgt=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"id");return i!==void 0&&(r.id=i),r}),qye=At({trending:ee.query(async({ctx:e})=>{let t="route-manga-trending",r=e.apiCache.get(t);if(r)return r;let n=await Vye(e,"",{query:"",page:1,limit:6,sort:"followed",status:"",type:"",ratings:["safe","suggestive"]}),i=n.items.map(s=>({id:s.id,provider:n.provider,title:s.title,description:typeof s.description=="string"?s.description:"",tags:Array.isArray(s.genres)?s.genres:[],year:typeof s.year=="number"?s.year:null,status:typeof s.status=="string"?s.status:null,cover:s.cover??""}));return e.apiCache.set(t,i,600),i}),search:ee.input(jgt()).query(async({ctx:e,input:t})=>{let r=t.provider||"",n=t.q||"",i=t.page||1;return j5(e,`route-manga-search-${r}-${n}-${i}-${t.sort||""}-${t.status||""}-${t.type||""}-${t.rating||""}-${t.mature||""}`,300,async()=>{try{let s=Yye({rating:t.rating,mature:t.mature}),o=t.type||"",a=o==="doujinshi"&&t.mature!=="1"?"":o,A=await Vye(e,r,{query:n,page:i,limit:t.limit||24,sort:t.sort||"popular",status:t.status||"",type:a,ratings:s});return{body:{...A,items:A.items??[]}}}catch(s){return U.error({err:s},"[Manga] search failed"),{body:{items:[],hasNext:!1,provider:r}}}})}),info:ee.input($gt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||""),i=String(t.rating||""),s=String(t.mature||"");return j5(e,`route-manga-info-${r}-${n}-${i}-${s}`,600,async()=>{try{if(!n)return{status:400,body:{error:"Missing id"}};let o=await $5(e,r)?.getDetail(n,Yye({rating:i,mature:s}));return o?{body:o}:{status:404,body:{error:"Not found"}}}catch(o){return U.error({err:o},"[Manga] info failed"),{status:500,body:{error:"Failed to load manga"}}}})}),pages:ee.input(Kgt()).query(async({ctx:e,input:t})=>{let r=String(t.provider||""),n=String(t.id||"");return j5(e,`route-manga-pages-${r}-${n}`,300,async()=>{try{return n?{body:{pages:await $5(e,r)?.getPages(n)??[]}}:{status:400,body:{error:"Missing id"}}}catch(i){return U.error({err:i},"[Manga] pages failed"),{body:{pages:[]}}}})})});var Xgt=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"q");n!==void 0&&(r.q=n),t.page!==void 0&&(r.page=parseInt(String(t.page),10)||1);let i=le(t,"sort");i!==void 0&&(r.sort=i);let s=le(t,"rating");return s!==void 0&&(r.rating=s),r}),zgt=()=>pe(e=>({rj:gt(ye(e),"rj")})),Wye=At({browse:ee.input(Xgt()).query(async({ctx:e,input:t})=>{let r=t.q||"",n=t.page||1,i=t.sort||"",s=t.rating||"";return jn(e,`route-asmr-browse-${r}-${n}-${i}-${s}-${i==="random"?Date.now():""}`,300,async()=>{try{let o=e.getJasmr();return o?await o.browse({query:r,page:n,sort:i,rating:s}):{shows:[],hasNext:!1}}catch(o){if(o.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:o},"[Asmr] browse failed"),{shows:[],hasNext:!1}}})}),work:ee.input(zgt()).query(async({ctx:e,input:t})=>{let r=t.rj;return jn(e,`route-asmr-work-${r}`,1800,async()=>{try{let n=e.getJasmr();if(!n)return{rjCode:r,description:"",tracks:[],images:[],chapters:[]};let i=String(r).trim().toUpperCase(),s=await n.getEpisodes(i),[o,a,A]=await Promise.all([n.getStreamUrls(i,"1"),n.getImages(i),n.getChapters(i)]);return{rjCode:i,description:s?.description||"",tracks:o?.[0]?.links||[],images:a,chapters:A}}catch(n){if(n.message==="AUTH_REQUIRED")throw Fc("jasmr");return U.error({err:n,rj:r},"[Asmr] work fetch failed"),{rjCode:r,description:"",tracks:[],images:[],chapters:[]}}})})});var K5="tracker_anilist_token",eQ="tracker_anilist_sync_state";function X5(e){if(!(!e||e<=0))return new Date(e*1e3).toISOString().slice(0,19).replace("T"," ")}function Zgt(e){return["Watching","Completed","On-Hold","Dropped","Planned"].includes(e)?e:void 0}async function Jye(e,t){return(await hi(e,"SELECT COUNT(DISTINCT episodeNumber) as total FROM watched_episodes WHERE showId = ?",[t]))?.total??0}async function z5(e){let r=(await xe.getByKey(e,K5))?.value;if(!r)throw new Error("AniList is not connected. Please log in first.");let n=new ma(r),i=await n.getViewer(),s=await n.fetchUserAnimeList(i.id),o=await _t.getAll(e),a=await Td(e,eQ),A=new Map;for(let B of s)A.set(B.mediaId,B);let u=new Map;for(let B of o){let w=(await ct.getById(e,B.id))?.anilistId;w==null||!Number.isFinite(w)||String(w)!==String(B.id)||u.has(w)||u.set(w,B)}let c=$R(u.keys(),A.keys(),a),l={pushed:0,pulled:0,merged:0,unchanged:0,errors:[]},d=[],h=[],f=[],g={},p=[],m=[],I=[],C=Math.floor(Date.now()/1e3);for(let B of c){let Q=u.get(B),w=A.get(B),R=String(B);try{if(Q&&!w){if(a[R]&&s.length>0){p.push(R),g[R]=void 0,l.pulled++;continue}let N=await Jye(e,R);m.push({mediaId:B,status:Zgt(Q.status),progress:N}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.pushed++;continue}if(!Q&&w){if(a[R]){if(w.entryId){I.push({showId:R,entryId:w.entryId}),g[R]=void 0,l.pushed++;continue}g[R]=void 0,l.pushed++;continue}U.debug({mediaId:B,remoteStatus:w.status},"[AniList Sync] Remote only -> pulling to local");let N=w.title.english||w.title.romaji||`Anime #${B}`;d.push({id:R,name:N,thumbnail:w.coverImage??"",status:w.status,nativeName:w.title.native??"",englishName:w.title.english??"",type:"TV"}),h.push({id:R,name:N,thumbnail:w.coverImage,nativeName:w.title.native,englishName:w.title.english,episodeCount:w.totalEpisodes,anilistId:B,episodeDuration:w.episodeDuration}),w.progress>0&&f.push({showId:R,from:1,to:w.progress,updatedAt:w.updatedAt}),g[R]={lastSyncedAt:C,remoteUpdatedAt:w.updatedAt},l.pulled++;continue}if(!Q&&!w&&a[R]){g[R]=void 0;continue}if(Q&&w){let N=await Jye(e,R),T=a[R]?.lastSyncedAt??0,Y=w.updatedAt||0,P=Math.max(N,w.progress),O=N>w.progress,W=w.progress>N,{status:oe,pull:ue}=jR(Q.status,w.status,Y,T),Ce=w.status!==Q.status;O||!ue&&Ce?(m.push({mediaId:B,status:oe,progress:P}),oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:C},l.merged++):ue||W?(oe!==Q.status&&d.push({id:R,name:Q.name,thumbnail:Q.thumbnail??"",status:oe,nativeName:Q.nativeName??"",englishName:Q.englishName??"",type:Q.type??""}),W&&f.push({showId:R,from:N+1,to:P,updatedAt:Y}),g[R]={lastSyncedAt:C,remoteUpdatedAt:Y},l.merged++):l.unchanged++}}catch(N){let T=N instanceof Error?N.message:String(N);U.warn({err:N,mediaId:B},"[AniList Sync] Entry failed"),l.errors.push(`${Q?.name??`Media ${B}`}: ${T}`)}}return(m.length>0||I.length>0||p.length>0)&&KR({totalDeletes:p.length+I.length,localItemCount:o.length,fetched:s.length,message:`AniList sync would delete ${p.length+I.length} shows but only ${s.length} were fetched. Aborting to protect your library - if you really removed that many shows on AniList, delete them locally first and sync again.`}),await XR(n,m,I),(d.length>0||h.length>0||f.length>0||p.length>0||Object.keys(g).length>0)&&await tt(e,async B=>{for(let w of d)await _t.upsert(B,w);for(let w of h)await ct.upsert(B,w);for(let w of f)for(let R=w.from;R<=w.to;R++)await Qr.insertIfMissing(B,{showId:w.showId,episodeNumber:String(R),watchedAt:X5(w.updatedAt)});for(let w of p)await _t.delete(B,w),await Qr.deleteByShow(B,w),await Zr.deleteByShow(B,w);let Q={...a};for(let[w,R]of Object.entries(g))R===void 0?delete Q[w]:Q[w]=R;await xe.upsert(B,eQ,JSON.stringify(Q))}),l}async function Z5(e,t,r=!1){let i=(await xe.getByKey(e,K5))?.value,s=new ma(i),o;if(i){let u=await s.getViewer();o=await s.fetchUserAnimeList(u.id)}else o=await s.fetchUserAnimeList(t);if(o.length===0)return 0;let a=Math.floor(Date.now()/1e3),A=await Td(e,eQ);return await tt(e,async u=>{r&&await xe.clearWatchlist(u);for(let c of o){let l=String(c.mediaId),d=c.title.english||c.title.romaji||`Anime #${c.mediaId}`;if(await _t.upsert(u,{id:l,name:d,thumbnail:c.coverImage??"",status:c.status,nativeName:c.title.native??"",englishName:c.title.english??"",type:"TV"}),await ct.upsert(u,{id:l,name:d,thumbnail:c.coverImage,nativeName:c.title.native,englishName:c.title.english,episodeCount:c.totalEpisodes,anilistId:c.mediaId}),c.progress>0)for(let h=1;h<=c.progress;h++)await Qr.insertIfMissing(u,{showId:l,episodeNumber:String(h),watchedAt:X5(c.updatedAt)});A[l]={lastSyncedAt:a,remoteUpdatedAt:c.updatedAt}}await xe.upsert(u,eQ,JSON.stringify(A))}),o.length}function jye(e){switch(e){case 1:return"Watching";case 2:return"Completed";case 3:return"On-Hold";case 4:return"Dropped";case 6:return"Planned";default:return null}}async function e0t(e){let t=await ys(e);if(t)return t.id;if(qi())try{let r=await ra({query:e,page:1,perPage:5});if(r.length>0)return r[0].id>0?r[0].id:null}catch{}return null}async function eG(e,t,r={}){let{erase:n=!1,useOfflineDb:i=!0,skipFallback:s=!1}=r,o=await mP(t);if(o.length===0)return 0;let a=[],A=[],u=[],c=[];for(let l of o){let d=jye(l.status);if(!d)continue;let h=i?pn.getByMalId(l.malId):null;if(h){let f=String(h.anilistId),g=h.title||l.titleEnglish||l.title||`MAL #${l.malId}`;a.push({id:f,name:g,thumbnail:h.thumbnail??l.imageUrl??void 0,status:d,englishName:l.titleEnglish??void 0,type:h.type??l.type??void 0}),(h.thumbnail||h.type||h.genres)&&A.push({id:f,thumbnail:h.thumbnail,type:h.type,genres:h.genres}),l.watchedEpisodes>0&&u.push({showId:f,progress:l.watchedEpisodes})}else c.push(l)}if(c.length>0&&!s)for(let d=0;d<c.length;d+=5){let h=c.slice(d,d+5);(await Promise.allSettled(h.map(async g=>{let p=await cc(g.malId).catch(()=>null);if(p?.anilistId)return p;let m=g.titleEnglish||g.title;if(!m)return null;let I=await e0t(m);return I?bi(String(I)).catch(()=>null):null}))).forEach((g,p)=>{if(g.status!=="fulfilled"||!g.value)return;let m=g.value,I=h[p],C=jye(I.status);if(!C)return;let B=m.anilistId?String(m.anilistId):m._id,Q=m.names?.english||m.names?.romaji||I.titleEnglish||I.title||`MAL #${I.malId}`;a.push({id:B,name:Q,thumbnail:m.thumbnail||I.imageUrl||void 0,status:C,englishName:I.titleEnglish??void 0,type:m.type??I.type??"TV"}),(m.thumbnail||m.type)&&A.push({id:B,thumbnail:m.thumbnail,type:m.type}),I.watchedEpisodes>0&&u.push({showId:B,progress:I.watchedEpisodes})})}return(a.length>0||n)&&await tt(e,async l=>{n&&await xe.clearWatchlist(l);for(let d of a)await _t.upsert(l,{id:d.id,name:d.name,thumbnail:d.thumbnail??"",status:d.status,nativeName:"",englishName:d.englishName??"",type:d.type??"TV"});for(let d of A)(d.thumbnail||d.type||d.genres)&&await ct.upsert(l,{id:d.id,thumbnail:d.thumbnail,type:d.type,genres:d.genres});for(let d of u)for(let h=1;h<=d.progress;h++)await Qr.insertIfMissing(l,{showId:d.showId,episodeNumber:String(h)})}),a.length}var tG="tracker_anilist_token",rG="tracker_anilist_user";function tQ(e){return e==null?{}:ye(e)}var t0t=()=>pe(e=>{let t=tQ(e);return{token:t.token,code:t.code,redirectUri:t.redirectUri}}),r0t=()=>pe(e=>({provider:tQ(e).provider})),nG=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase}}),n0t=()=>pe(e=>{let t=tQ(e);return{username:t.username,erase:t.erase,useOfflineDb:t.useOfflineDb,skipFallback:t.skipFallback}}),i0t=()=>pe(e=>({direction:tQ(e).direction}));function $ye(e){return e.includes("private")||e.includes("not found")?Mc(e):e.includes("blocked")||e.includes("HTTP 429")?PBe(e):yr(e)}var Kye=At({status:ee.query(async({ctx:e})=>{try{let t=await xe.getByKey(e.db,tG),r=await xe.getByKey(e.db,rG),n=null;if(r?.value)try{n=JSON.parse(r.value)}catch(i){U.warn({err:i},"The stored tracker user is not valid json"),n=null}return{anilist:{connected:!!t?.value,user:n}}}catch{throw yr("Failed to read tracker status")}}),anilistAuth:ee.input(t0t()).mutation(async({ctx:e,input:t})=>{let r=typeof t.token=="string"?t.token.trim():"";if(!r)throw it("Access token is required");try{let i=await new ma(r).getViewer();return await tt(e.db,async s=>{await xe.upsert(s,tG,r),await xe.upsert(s,rG,JSON.stringify(i))}),{success:!0,user:i}}catch(n){throw GBe(n instanceof Error?n.message:"Authentication failed")}}),anilistDisconnect:ee.mutation(async({ctx:e})=>{try{return await tt(e.db,async t=>{await xe.upsert(t,tG,""),await xe.upsert(t,rG,"")}),{success:!0}}catch{throw yr("Failed to disconnect")}}),sync:ee.input(r0t()).mutation(async({ctx:e,input:t})=>{let{provider:r="anilist"}=t;if(r!=="anilist")throw it(`Provider "${r}" is not supported yet`);try{return{success:!0,summary:await z5(e.db)}}catch(n){throw yr(n instanceof Error?n.message:"Sync failed")}}),anilistImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{return{success:!0,count:await Z5(e.db,r.trim(),n===!0)}}catch(i){throw yr(i instanceof Error?i.message:"Import failed")}}),malImport:ee.input(n0t()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n,useOfflineDb:i,skipFallback:s}=t;if(!r||typeof r!="string")throw it("MAL username is required");try{return{success:!0,count:await eG(e.db,r.trim(),{erase:n===!0,useOfflineDb:i!==!1,skipFallback:s===!0})}}catch(o){throw $ye(o instanceof Error?o.message:"Import failed")}}),mangaSync:ee.input(i0t()).mutation(async({ctx:e,input:t})=>{let{direction:r}=t;try{let n=e.mangaDb;if(!n||n.isClosedCheck())throw vd("Manga database is not ready");let i=r==="pull-only"?"pull-only":"two-way",s=await p5(e.db,n,{direction:i});return{success:!0,summary:s.summary,details:s.details,direction:i}}catch(n){throw n instanceof nt?n:yr(n instanceof Error?n.message:"Manga sync failed")}}),mangaImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,count:await m5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:yr(i instanceof Error?i.message:"Import failed")}}),mangaMalImport:ee.input(nG()).mutation(async({ctx:e,input:t})=>{let{username:r,erase:n}=t;if(!r||typeof r!="string")throw it("Username is required");try{let i=e.mangaDb;if(!i||i.isClosedCheck())throw vd("Manga database is not ready");return{success:!0,...await I5(e.db,i,r.trim(),n===!0)}}catch(i){throw i instanceof nt?i:$ye(i instanceof Error?i.message:"Import failed")}})});var Ms={getCoreStats:async e=>(await te(e).all(y`
895
895
  SELECT
896
896
  (SELECT SUM(
897
897
  CASE WHEN we.currentTime > 0 THEN we.currentTime
@@ -982,7 +982,7 @@ If you want to call this function on the server, see https://trpc.io/docs/v11/se
982
982
  (SELECT COUNT(*) FROM watched_episodes we WHERE we.showId = w.id) as episodesWatched,
983
983
  COALESCE(sm.popularityScore, 0) as popularityScore
984
984
  FROM watchlist w
985
- LEFT JOIN shows_meta sm ON sm.id = w.id`),getAllAnilistIds:e=>te(e).all(y`SELECT anilistId FROM shows_meta WHERE anilistId IS NOT NULL`)};function Xye(e,t,r){if(!e)return[];try{return e.startsWith("[")?JSON.parse(e):e.split(",").map(n=>n.trim())}catch(n){return U.warn({err:n,showId:t},`Failed to parse genres for ${r}`),[]}}async function zye(e){let[t,r,n,i,s,o,a,A]=await Promise.all([Ms.getCoreStats(e),Ms.getActivityGrid(e),Ms.getHourlyDist(e),Ms.getSeasonality(e),Ms.getAllWatches(e),Ms.getWatchedShowsMeta(e),Ms.getDroppedShows(e),Ms.getCompletionVelocities(e)]),u=r.length>0?Math.max(...r.map(C=>C.count)):0,c=[];if(s.length>0){let C=s[0].effectiveSeconds??s[0].currentTime;for(let B=1;B<s.length;B++){let Q=new Date(s[B-1].watchedAt).getTime(),R=new Date(s[B].watchedAt).getTime()-Q;Number.isFinite(R)&&R>0&&R<36e5?C+=s[B].effectiveSeconds??s[B].currentTime:(c.push(C),C=s[B].effectiveSeconds??s[B].currentTime)}c.push(C)}let l=c.length>0?Math.round(c.reduce((C,B)=>C+B,0)/c.length/60):0,d={},h=0,f=0;for(let C of o){let B=Xye(C.genres,C.id,"insights");for(let Q of B)d[Q]=(d[Q]||0)+1;if(C.popularityScore){let Q=C.popularityScore;Q>10&&(Q=Q/10),h+=Q,f++}}let g=Object.entries(d).sort((C,B)=>B[1]-C[1])[0]?.[0],m={Action:"Shonen Warrior",Romance:"Hopeless Romantic",Comedy:"Chaos Enjoyer","Slice of Life":"Vibe Seeker",Horror:"Fearless Watcher",Fantasy:"Isekai Traveller","Sci-Fi":"Future Scientist",Drama:"Feels Collector"}[g||""]||"Anime Enthusiast",I=A.length>0?Math.round(A.reduce((C,B)=>C+B.daysToFinish,0)/A.length):0;return{totalHours:Math.round((t?.totalSeconds||0)/3600),totalEpisodes:t?.totalEpisodes||0,totalAnime:t?.totalAnime||0,completedAnime:t?.completedCount||0,completionRate:t?.totalWatchlist>0?Math.round(t.completedCount/t.totalWatchlist*100):0,persona:m,bingeFactor:u,avgSessionMinutes:l,avgCompletionDays:I,popularityScore:f>0?Math.round(h/f):0,genreSplit:Object.entries(d).map(([C,B])=>({name:C,count:B})).sort((C,B)=>B.count-C.count).slice(0,8)||[],activityGrid:r||[],hourlyDist:Array.from({length:24},(C,B)=>{let Q=B.toString().padStart(2,"0");return{hour:Q,count:n?.find(w=>w.hour===Q)?.count||0}})||[],seasonality:Array.from({length:12},(C,B)=>{let Q=(B+1).toString().padStart(2,"0");return{month:Q,seconds:i?.find(w=>w.month===Q)?.seconds||0}})||[],droppedShows:(a||[]).slice(0,5)}}async function Zye(e){let t=await Ms.getWatchedEpisodesWithMeta(e),r={};for(let i of t){let s=Xye(i.genres,i.showId,"genre cards"),o=(i.effectiveSeconds??i.currentTime)||0,a=i.popularityScore||0;a>10&&(a=a/10);for(let A of s)r[A]||(r[A]={count:0,totalTime:0,scores:[],showWatches:{},showMeta:{}}),r[A].count++,r[A].totalTime+=o,a>0&&r[A].scores.push(a),r[A].showWatches[i.showId]=(r[A].showWatches[i.showId]||0)+1,(i.name||i.thumbnail)&&(r[A].showMeta[i.showId]={name:i.name,nativeName:i.nativeName,englishName:i.englishName,thumbnail:i.thumbnail})}let n=Object.entries(r).map(([i,s])=>{let o=Object.entries(s.showWatches).sort((a,A)=>A[1]-a[1]).slice(0,4).map(([a])=>({id:a,name:s.showMeta[a]?.name||"",nativeName:s.showMeta[a]?.nativeName,englishName:s.showMeta[a]?.englishName,thumbnail:s.showMeta[a]?.thumbnail||""}));return{rank:0,name:i,count:s.count,meanScore:s.scores.length>0?s.scores.reduce((a,A)=>a+A,0)/s.scores.length:0,timeWatched:s0t(s.totalTime),topShows:o}});return n.sort((i,s)=>s.count-i.count),n.forEach((i,s)=>{i.rank=s+1}),n}function s0t(e){let t=Math.floor(e/86400),r=Math.floor(e%86400/3600),n=Math.floor(e%3600/60);return t>0?`${t} days ${r>0?`${r} hours`:""}`:r>0?`${r} hours${n>0?` ${n} mins`:""}`:`${n} mins`}function eQe(e){if(!e)return[];try{if(e.startsWith("[")){let t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}return e.split(",").map(t=>t.trim()).filter(Boolean)}catch{return[]}}async function o0t(e){let[t,r,n]=await Promise.all([Ms.getLibraryShowsWithGenres(e),Ms.getAllAnilistIds(e),Ms.getWatchedEpisodesWithMeta(e)]),i={},s={};for(let c of t){let l=eQe(c.genres);if(c.status==="Completed")for(let d of l)i[d]=(i[d]||0)+1;else if(c.status==="Dropped")for(let d of l)s[d]=(s[d]||0)+1}let o={};for(let c of n){let l=c.englishName||c.name||c.showId;for(let d of eQe(c.genres)){o[d]||(o[d]=new Map);let h=o[d].get(c.showId)||{title:l,count:0};h.count+=1,o[d].set(c.showId,h)}}let a={},A=Object.entries(i).sort((c,l)=>l[1]-c[1]).slice(0,6);for(let[c]of A)a[c]=[...o[c]?.values()||[]].sort((l,d)=>d.count-l.count).slice(0,2).map(l=>l.title);let u=new Set;for(let c of t)/^\d+$/.test(c.id)&&u.add(Number(c.id));for(let c of r)c.anilistId&&u.add(c.anilistId);return{genreComp:i,genreDrop:s,exemplars:a,knownIds:[...u]}}var a0t="id title { romaji english } coverImage { large } averageScore popularity episodes seasonYear format genres isAdult status";function A0t(e,t){let r=Math.max(1,...Object.values(e)),n={};for(let[i,s]of Object.entries(e)){let o=t[i]||0;n[i]=s/r*(s/(s+o))}return n}function u0t(e){let t=Object.entries(e).sort((i,s)=>s[1]-i[1]).slice(0,4).map(([i])=>i);for(;t.length<2;)t.push("Fantasy");let r=[[t[0],t[1]],[t[0],t[2]||t[1]],[t[1],t[2]||t[0]],[t[0],t[3]||t[1]]],n=new Set;return r.filter(i=>{let s=[...i].sort().join("|");return n.has(s)?!1:(n.add(s),!0)})}function c0t(e,t,r=2){let n=new Map;for(let i of t)for(let s of e[i]||[])n.set(s,(n.get(s)||0)+1);return[...n.entries()].sort((i,s)=>s[1]-i[1]).slice(0,r).map(([i])=>i)}async function l0t(e){let t=new Set(e.knownIds||[]);if(t.size===0)return[];let r=A0t(e.genreComp,e.genreDrop),n=.15,i=Object.values(r).reduce((u,c)=>u+c,0)||1,s=new Map;for(let u of u0t(r))try{let c=await rr(`query ($g: [String]) { Page(page: 1, perPage: 20) { media(genre_in: $g, type: ANIME, status: FINISHED, isAdult: false, averageScore_greater: 68, sort: SCORE_DESC) { ${a0t} } } }`,{g:u});for(let l of c?.data?.Page?.media||[])s.has(l.id)||s.set(l.id,l)}catch{}if(s.size===0)return[];let o=[];for(let u of s.values()){if(t.has(u.id)||u.isAdult||u.format==="MUSIC"||u.format==="SPECIAL")continue;let c=u.genres||[],d=.65*(c.reduce((h,f)=>h+(r[f]??n),0)/i)+.25*((u.averageScore||70)/100)+.1*Math.min(1,(u.popularity||0)/2e5);o.push({m:u,score:d,overlap:c.filter(h=>(r[h]??0)>.3)})}o.sort((u,c)=>c.score-u.score);let a=o.slice(0,15),A=new Map;try{let u=await rr("query ($ids: [Int]) { Page(page: 1, perPage: 50) { media(id_in: $ids, type: ANIME) { id relations { edges { relationType node { id title { romaji english } type } } } } } }",{ids:a.map(c=>c.m.id)});for(let c of u?.data?.Page?.media||[])A.set(c.id,c)}catch{}return a.map(u=>{let l=A.get(u.m.id)?.relations?.edges?.find(m=>m.relationType==="PREQUEL"&&m.node?.type==="ANIME")?.node,d=u.score,h="entry",f=null;l&&l.id&&!t.has(l.id)?(h="sequel",f=l.title?.english||l.title?.romaji||null,d-=.3):l&&(h="continue",d+=.05);let g=u.m.genres||[],p=u.m.title?.english||u.m.title?.romaji||"Unknown";return{id:u.m.id,title:p,url:`https://anilist.co/anime/${u.m.id}`,cover:u.m.coverImage?.large||null,year:u.m.seasonYear??null,format:u.m.format||"TV",episodes:u.m.episodes??null,averageScore:u.m.averageScore??null,genres:g,matchPct:Math.round(d*100),sharedGenres:u.overlap,exemplars:c0t(e.exemplars,g),kind:h,prequelTitle:f}})}var Ex=null;function d0t(e){return JSON.stringify([e.genreComp,e.genreDrop,e.knownIds.length])}async function h0t(e,t){if(!Ex||Ex.hash!==t)try{let r=await l0t(e);r.length>0&&(Ex={hash:t,candidates:r})}catch(r){U.warn({err:r?.message},"Recommendation candidates failed, reusing previous")}return Ex?.candidates||[]}async function tQe(e){let t=await o0t(e);return h0t(t,d0t(t))}var rQe=At({summary:ee.query(async({ctx:e})=>zye(e.db)),genreCards:ee.query(async({ctx:e})=>Zye(e.db)),recommendations:ee.query(async({ctx:e})=>({candidates:await tQe(e.db)}))});Nn();zd();async function iG(e,t,r){let n=ae.IS_DEV?ae.REMOTE_FOLDER_DEV:ae.REMOTE_FOLDER_PROD;await Yb({db:t,mangaDb:e.mangaDb,tvDb:e.tvDb,asmrDb:e.asmrDb},{remoteFolder:n,preferredProvider:r})}var f0t=()=>pe(e=>{let t=ye(e);return{clientId:t.clientId,clientSecret:t.clientSecret,workerUrl:t.workerUrl}}),g0t=()=>pe(e=>{let t=ye(e);if(typeof t.clientId!="string")throw it("clientId required");return{clientId:t.clientId}}),E0t=()=>pe(e=>({provider:ye(e).provider})),p0t=()=>pe(e=>({remote:ye(e).remote})),m0t=()=>pe(e=>({port:ye(e).port})),nQe=At({configStatus:ee.query(async()=>{let e=!!ae.GOOGLE_AUTH_WORKER_URL,t=!!process.env.GOOGLE_CLIENT_ID&&!!process.env.GOOGLE_CLIENT_SECRET;return{hasConfig:e||t,useWorker:e}}),googleAuth:ee.query(async()=>({useWorker:!!ae.GOOGLE_AUTH_WORKER_URL,hasCustomWorkerUrl:!!process.env.GOOGLE_AUTH_WORKER_URL,hasCustomClientId:!!process.env.GOOGLE_CLIENT_ID,hasClientSecret:!!process.env.GOOGLE_CLIENT_SECRET})),saveGoogleAuth:ee.input(f0t()).mutation(async({input:e})=>{let{clientId:t,clientSecret:r,workerUrl:n}=e,i={};return typeof t=="string"&&(i.GOOGLE_CLIENT_ID=t),typeof r=="string"&&(i.GOOGLE_CLIENT_SECRET=r),typeof n=="string"&&(i.GOOGLE_AUTH_WORKER_URL=n),await Rn(i),typeof n=="string"&&(ae.GOOGLE_AUTH_WORKER_URL=n),typeof t=="string"&&(ae.GOOGLE_CLIENT_ID=t||void 0),typeof r=="string"&&(ae.GOOGLE_CLIENT_SECRET=r||void 0),await Jg(),{success:!0}}),saveGithubAuth:ee.input(g0t()).mutation(async({input:e})=>(await Rn({GITHUB_CLIENT_ID:e.clientId}),{success:!0})),rcloneSettings:ee.query(async()=>{let e=await Ui.listRemotes();return{remote:ae.RCLONE_REMOTE||"",availableRemotes:e,activeRemote:Ui.isActive()?Ui.getRemoteName():null}}),syncSettings:ee.query(async()=>({activeProvider:process.env.SYNC_PROVIDER||"default",actualActiveProvider:j2(),authenticatedProviders:{github:as.isAuthenticated(),google:Fi.isAuthenticated(),rclone:Ui.isActive()}})),saveSyncProvider:ee.input(E0t()).mutation(async({input:e})=>{let{provider:t}=e;return await Rn({SYNC_PROVIDER:t==="default"?"":t}),await Jg(),{success:!0,activeProvider:process.env.SYNC_PROVIDER||"default"}}),githubStatus:ee.query(async()=>{try{let e=await as.getUserProfile();return{authenticated:!!e,user:e,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}catch(e){return U.error({err:e},"Failed to fetch GitHub auth status"),{authenticated:!1,user:null,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}}),githubStart:ee.mutation(async({ctx:e})=>await as.startDeviceAuth(e.db,(r,n)=>iG(e,r,n))),githubPoll:ee.query(async()=>as.getDeviceState()),githubLogout:ee.mutation(async()=>(await as.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0})),saveRclone:ee.input(p0t()).mutation(async({ctx:e,input:t})=>{let{remote:r}=t;return await Rn({RCLONE_REMOTE:r,SYNC_PROVIDER:"rclone"}),await iG(e,e.db,"rclone"),{success:!0}}),setServerPort:ee.input(m0t()).mutation(async({input:e})=>{let t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)throw it("Port must be an integer between 1 and 65535");return await Rn({PORT:String(t)}),U.info({port:t},"Server port saved. Restart required to apply."),{success:!0,port:t}}),googleLogin:ee.mutation(async({ctx:e})=>{if(Fi.isAuthenticated()){if(await Fi.getUserProfile())return await Rn({SYNC_PROVIDER:"google"}),await iG(e,e.db,"google"),{url:null,authenticated:!0};U.warn("Google tokens found but invalid. Clearing and requesting new auth."),await Fi.logout()}return{url:await Fi.getAuthUrl(),authenticated:!1}}),user:ee.query(async()=>await Fi.getUserProfile()),logout:ee.mutation(async()=>(await Fi.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0}))});var iQe=()=>pe(e=>{let t=ye(e),r={date:gt(t,"date")},n=le(t,"format");return n!==void 0&&(r.format=n),r}),sQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"format");return n!==void 0&&(r.format=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,12,50,"size")),r}),oQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"query");n!==void 0&&(r.query=n),t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let i=le(t,"sortBy");i!==void 0&&(r.sortBy=i);let s=le(t,"type");s!==void 0&&(r.type=s);let o=le(t,"status");o!==void 0&&(r.status=o);let a=le(t,"season");a!==void 0&&(r.season=a);let A=Ls(t,"year");A!==void 0&&(r.year=A);let u=le(t,"country");u!==void 0&&(r.country=u);let c=le(t,"genres");c!==void 0&&(r.genres=c);let l=le(t,"excludeGenres");l!==void 0&&(r.excludeGenres=l);let d=le(t,"excludeTags");d!==void 0&&(r.excludeTags=d);let h=Ls(t,"minScore");h!==void 0&&(r.minScore=h);let f=Ls(t,"minEpisodes");f!==void 0&&(r.minEpisodes=f);let g=le(t,"adult");return g!==void 0&&(r.adult=g),r}),aQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"title");return n!==void 0&&(r.title=n),r}),AQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");return i!==void 0&&(r.episodeNumber=i),r}),uQe=()=>pe(e=>{let t=ye(e),r={};t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,14,50,"size"));let n=le(t,"format");return n!==void 0&&(r.format=n),r}),cQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"sort");return n!==void 0&&(r.sort=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,20,50,"size")),r}),lQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"mode");(i==="sub"||i==="dub")&&(r.mode=i);let s=le(t,"provider");return s!==void 0&&(r.provider=s),r}),dQe=()=>pe(e=>({id:gt(ye(e),"id")})),hQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");i!==void 0&&(r.episodeNumber=i);let s=le(t,"mode");(s==="sub"||s==="dub")&&(r.mode=s);let o=le(t,"provider");return o!==void 0&&(r.provider=o),r}),fQe=()=>pe(e=>{let t=ye(e),r={};for(let o of["provider","query","type","status","season","country","genres","genre","excludeGenres","sortBy","order","studio","blacklist"]){let a=le(t,o);a!==void 0&&(r[o]=a)}t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let n=Ls(t,"year");n!==void 0&&(r.year=n);let i=Ls(t,"minScore");i!==void 0&&(r.minScore=i);let s=Ls(t,"minEpisodes");return s!==void 0&&(r.minEpisodes=s),r}),gQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"nativeId");i!==void 0&&(r.nativeId=i);let s=le(t,"title");s!==void 0&&(r.title=s);let o=le(t,"thumbnail");return o!==void 0&&(r.thumbnail=o),r});function EQe(e,t){let r=t?.toLowerCase();return r&&e.getProviders()[r]||null}function _d(e,t){let r=(t||"").toLowerCase(),n=e.getProviders();if(!r||!n[r]||r==="mal"||r==="anilist")return!1;let i=pQe(e);return i?i.has(r):!0}function pQe(e){let t=e.getCatalog();return!t||t.length===0?null:new Set(t.filter(r=>r.mature&&(r.kind??"anime")==="anime"&&r.loaded).map(r=>r.id.toLowerCase()))}async function sG(e,t,r){let n=e.getProviders(),i=pQe(e),s=i?[...i]:Object.keys(n),o=[r,...s].filter(A=>!!A&&A!=="mal"&&A!=="anilist"&&!!n[A]),a=new Set;for(let A of o)if(!a.has(A)){a.add(A);try{let u=await n[A].resolveShowId?.(t);if(u)return{provider:n[A],nativeId:u}}catch{}}return null}function lm(e){if(typeof e!="string"||!e.trim())return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length>0?t:void 0}var dm=e=>Array.isArray(e)&&e.length>0,mQe=At({schedule:ee.input(iQe()).query(async({ctx:e,input:t})=>{let r=t.date,n=t.format||"TV";return jn(e,`schedule-${r}-${n}`,1800,async()=>{try{let i=new Date(r+"T00:00:00.000Z"),s=n==="ADULT";return await kP(i,s?void 0:n,s)}catch(i){return U.error({err:i,date:r},"Schedule fetch failed"),[]}},dm)}),latestReleases:ee.input(sQe()).query(async({ctx:e,input:t})=>{let r=t.format||"TV",n=t.page||1,i=t.size||12;return jn(e,`latest-releases-${r}-${n}-${i}`,300,async()=>{try{return await NP(r,n,i)}catch(s){return U.error({err:s},"Latest releases fetch failed"),[]}},dm)}),search:ee.input(oQe()).query(async({ctx:e,input:t})=>{let r={};return t.query!==void 0&&(r.query=t.query),t.page!==void 0&&(r.page=String(t.page)),t.limit!==void 0&&(r.limit=String(t.limit)),t.sortBy!==void 0&&(r.sortBy=t.sortBy),t.type!==void 0&&(r.type=t.type),t.status!==void 0&&(r.status=t.status),t.season!==void 0&&(r.season=t.season),t.year!==void 0&&(r.year=String(t.year)),t.country!==void 0&&(r.country=t.country),t.genres!==void 0&&(r.genres=t.genres),t.excludeGenres!==void 0&&(r.excludeGenres=t.excludeGenres),t.excludeTags!==void 0&&(r.excludeTags=t.excludeTags),t.minScore!==void 0&&(r.minScore=String(t.minScore)),t.minEpisodes!==void 0&&(r.minEpisodes=String(t.minEpisodes)),t.adult!==void 0&&(r.adult=t.adult),jn(e,`search-${JSON.stringify(r)}`,1800,async()=>{try{return await pf({query:t.query||"",page:t.page||1,perPage:t.limit||14,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),tag_not_in:lm(t.excludeTags),averageScore_greater:t.minScore,episodes_greater:t.minEpisodes,isAdult:t.adult==="true"?!0:t.adult==="false"?!1:void 0,sort:t.sortBy})}catch(n){return U.error({err:n},"search failed"),[]}},dm)}),seasonal:ee.input(uQe()).query(async({ctx:e,input:t})=>{let r=t.page||1,n=t.size||14,i=t.format;return jn(e,`seasonal-${i||"ALL"}-${r}-${n}`,300,async()=>{try{return await RP(r,n,i)}catch(s){return U.error({err:s},"Seasonal fetch failed"),[]}},dm)}),popularList:ee.input(cQe()).query(async({ctx:e,input:t})=>{let r=t.sort==="POPULARITY_DESC"?"POPULARITY_DESC":"TRENDING_DESC",n=t.page||1,i=t.size||20;return jn(e,`popular-list-${t.sort||"TRENDING_DESC"}-${n}-${i}`,300,async()=>{try{return await xP(n,i,r)}catch(s){return U.error({err:s},"Popular list fetch failed"),[]}},dm)}),spotlight:ee.query(async({ctx:e})=>jn(e,"spotlight",300,async()=>{try{return await vP(1,20)}catch(t){return U.error({err:t},"Spotlight fetch failed"),[]}},dm)),genresAndTags:ee.query(async()=>{try{return await ZO()}catch(e){throw U.error({err:e},"genres-and-tags failed"),yr("Failed to load genres")}}),anilistStatus:ee.query(async()=>{let e=!Qi();return e||OC().catch(()=>{}),{available:e,wasDownAtBoot:cT()}}),systemNotifications:ee.query(async()=>{let e=[];return cT()&&Qi()&&e.push({id:"system-anilist-down",type:"system",title:"AniList API",message:"AniList metadata API is currently down. dango is experiencing degraded performance. MAL + Kitsu is being used as a fallback in the meantime. Some features may be limited until service is restored.",icon:"warning",createdAt:Date.now()}),e})});var I0t=e=>Array.isArray(e)&&e.length>0,IQe=At({matureResolve:ee.input(aQe()).query(async({ctx:e,input:t})=>jn(e,`mature-resolve-${t.title||""}`,3600,async()=>{try{let r=(t.title||"").trim();if(!r)throw it("title is required");let n=await ys(r);if(n){let s=n.id;return{id:typeof s=="number"&&s<0?`mal-${Math.abs(s)}`:s}}let i=await EP(e.malCacheStore(),r);if(i)return{id:i,provider:"mal"};throw Mc("No match found")}catch(r){throw r instanceof nt?r:(U.error({err:r},"mature resolve failed"),yr("Resolve failed"))}},I0t)),matureSearch:ee.input(fQe()).query(async({ctx:e,input:t})=>{let r=(t.provider||"anilist").toLowerCase();if(r!=="anilist"&&r!=="mal"&&!_d(e,r))throw it("Unknown mature provider");let n={};for(let[i,s]of Object.entries(t))s!==void 0&&(n[i]=String(s));return jn(e,`mature-search-${JSON.stringify(n)}`,600,async()=>{try{let i=t.query||"",s=t.page||1,o=t.limit||14;if(r==="anilist"){let a=await pf({query:i,page:s,perPage:o,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy});return{data:a,hasMore:a.length>=o}}if(_d(e,r)){let a=e.getProviders()[r];if(a?.browse){let u=t.genre||t.genres||void 0,c=await a.browse({query:i,page:s,limit:o,pageSize:o,genre:u,genres:t.genres||u,order:t.order||t.sortBy||void 0,sort:t.sortBy||t.order||void 0,studio:t.studio||void 0,blacklist:t.blacklist||void 0});return{data:c.shows,hasMore:c.hasMore,...c.total!==void 0?{total:c.total}:{},...c.genres?{genres:c.genres}:{}}}return{data:(await a.search({query:i})).map(u=>({...u,isAdult:!0})),hasMore:!1}}if(r==="mal"){let a=[];try{a=await Kl(e.malCacheStore(),{query:i,page:s,perPage:50,format:t.type,status:t.status,genre:t.genres||void 0,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy,averageScore_greater:t.minScore,episodes_greater:t.minEpisodes})}catch(c){U.error({err:c},"mal mature search failed")}let A=a.map(c=>({...cr(c),isAdult:!0}));return{data:A.slice(0,o),hasMore:A.length>=o}}return{data:[],hasMore:!1}}catch(i){return U.error({err:i},"mature search failed"),{data:[],hasMore:!1}}},i=>!!i&&typeof i=="object"&&Array.isArray(i.data))}),matureFilters:ee.query(async({ctx:e})=>{try{let t=e.getCatalog()??[],r={};for(let n of t)!n.mature||(n.kind??"anime")!=="anime"||!n.loaded||(r[n.id]={label:n.label,...n.browse?{browse:n.browse}:{},...n.facets?.genres?.length?{genres:n.facets.genres}:{},...n.facets?.orders?.length?{orders:n.facets.orders}:{}});return{providers:r}}catch(t){throw U.error({err:t},"mature filters failed"),yr("Failed to load filters")}}),matureAllocate:ee.input(gQe()).mutation(async({ctx:e,input:t})=>{try{let r=String(t.provider||"").toLowerCase(),n=String(t.nativeId||"").trim(),i=String(t.title||"").trim(),s=String(t.thumbnail||"");if(!r||!_d(e,r))throw it("Unknown provider");if(!n||!i)throw it("nativeId and title are required");return{id:(await ko.allocate(e.db,{provider:r,nativeId:n,title:i,thumbnail:s})).id}}catch(r){throw r instanceof nt?r:(U.error({err:r},"temp show allocate failed"),yr("Allocate failed"))}})});var C0t=e=>Array.isArray(e)&&e.length>0,CQe=At({skipTimes:ee.input(AQe()).query(async({input:e})=>{let t=e.showId||"",r=e.episodeNumber||"";try{if(/^\d+$/.test(t)){let n=await Sr(`https://api.aniskip.com/v1/skip-times/${t}/${r}?types=op&types=ed`,{},{timeoutMs:1e4});if(n.ok)return await Vt(n)}return{found:!1,results:[]}}catch(n){return U.warn({err:n,showId:t,episodeNumber:r},"Skip-times fetch failed"),{found:!1,results:[]}}}),episodes:ee.input(lQe()).query(async({ctx:e,input:t})=>{let r=t.showId;return jn(e,`episodes-${r||""}`,3600,async()=>{let n=r;if(!n)return{episodes:[]};let i=e.db,s=e.getProviders(),o=await vr(i,n),a=jA(o);if(a)try{let l=await cc(a);l?.anilistId&&l.anilistId>0&&(o=String(l.anilistId))}catch{}if(vg(o)){try{let l=await ko.getById(i,o);if(!l||!_d(e,l.provider))return{episodes:[]};let d=String(t.provider||"").toLowerCase(),h=s[l.provider];if(h&&(!d||d===l.provider)){let g=await h.getEpisodes(l.nativeId,t.mode);return g?.episodes?.length?g:{episodes:[]}}let f=await sG(e,l.title,d);if(f){let g=await f.provider.getEpisodes(f.nativeId,t.mode);if(g?.episodes?.length)return g}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(String(t.provider||"animepahe"));U.warn({err:l,showId:o},"Temp show episodes fetch failed")}return{episodes:[]}}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))try{if(s.animepahe)return await s.animepahe.getEpisodes(o,t.mode)||{episodes:[]}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc("animepahe");return U.warn({err:l,showId:o},"Animepahe episodes fetch failed"),{episodes:[]}}if(/^(mal-\d+|-?\d+)$/i.test(o)){let l=[];try{l=await KC(o)}catch(d){U.error({err:d,showId:o},"Episodes fetch failed")}if(l.length===0){let d=Math.abs(parseInt(o,10));if(!Number.isFinite(d))return{episodes:l};try{let f=(await $l(e.malCacheStore(),d)).detail?.episodes;f&&f>0&&f<=500&&(l=Array.from({length:f},(g,p)=>(p+1).toString()))}catch{}}if(l.length===0){let d=t.provider?.toLowerCase(),h=d?s[d]:void 0;if(h?.isDirectId?.(o))try{let f=await h.getEpisodes(o,t.mode);if(f?.episodes?.length)return f}catch(f){if(f.message==="AUTH_REQUIRED")throw Fc(d||"animepahe");U.warn({err:f,showId:o,provider:d},"Episodes fetch failed")}}return{episodes:l}}let u=t.provider?.toLowerCase(),c=u?s[u]:void 0;if(c)try{let l=await c.getEpisodes(o,t.mode);if(l?.episodes?.length)return l}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(u||"animepahe");U.warn({err:l,showId:o,provider:u},"Episodes fetch failed")}return{episodes:[]}},C0t)}),showMeta:ee.input(dQe()).query(async({ctx:e,input:t})=>{let r=t.id;return jn(e,`meta-${r}`,3600,async()=>{let n=e.db,i=await vr(n,r);if(vg(i)){let o=await ko.getById(n,i);return!o||!_d(e,o.provider)?{}:{_id:o.id,id:o.id,name:o.title,englishName:o.title,thumbnail:o.thumbnail||"",type:"TV",isAdult:!0,status:"UNKNOWN",provider:o.provider,nativeId:o.nativeId}}if(/^(mal-\d+|-?\d+)$/i.test(i)){let o=null;try{o=await bi(i)}catch(a){U.warn({err:a,id:i},"AniList show-meta fetch failed, trying local cache");let A=await ct.getById(n,i);if(A){if(typeof A.genres=="string")try{A.genres=JSON.parse(A.genres)}catch{A.genres=[]}return A}}if(o){let a=o.thumbnail?.trim()?o.thumbnail:void 0,A=!!a;try{await ct.upsert(n,{id:i,name:o.name,thumbnail:a,nativeName:o.nativeName,englishName:o.englishName,popularityScore:o.score??(o.averageScore!=null?o.averageScore/10:void 0),genres:o.genres?JSON.stringify(o.genres.map(u=>typeof u=="string"?u:u?.name).filter(Boolean)):void 0,status:o.status,episodeCount:o.episodeCount!=null?Number(o.episodeCount):void 0,type:o.type,anilistId:o.anilistId})}catch{}if(A&&a){let u=await _t.getById(n,i);if(u&&u.thumbnail!==a)try{await _t.updateThumbnail(n,i,a)}catch{}}}if(/^(mal-\d+|-\d+)$/i.test(i)&&o?.anilistId&&o.anilistId>0)try{Ia.set(n,i,String(o.anilistId))}catch{}return o||{}}return{}},n=>!!n)}),video:ee.input(hQe()).query(async({ctx:e,input:t})=>{let r=e.db,n=e.getProviders();try{let i=t.showId,s=jA(i);if(s)try{let h=await cc(s);h?.anilistId&&h.anilistId>0&&(i=String(h.anilistId))}catch{}if(vg(i)){try{let h=await ko.getById(r,i);if(!h||!_d(e,h.provider))return[];let f=String(t.provider||"").toLowerCase(),g=n[h.provider];if(g&&(!f||f===h.provider))return await g.getStreamUrls(h.nativeId,t.episodeNumber,t.mode)||[];let p=await sG(e,h.title,f);if(p)return await p.provider.getStreamUrls(p.nativeId,t.episodeNumber,t.mode)||[]}catch(h){U.error({err:h,showId:i},"Temp show video fetch failed")}return[]}let a=t.provider?.toLowerCase(),A=jA(i)!==null,c=!!!(a&&n[a]?.isDirectId?.(i))&&(/^\d+$/.test(i)||A);if(a&&c){let h=await ct.getById(r,i),f=h?.englishName||h?.name,g=null;if(!f)try{g=await bi(i),f=g?.englishName||g?.name,g&&f&&await ct.upsert(r,{id:i,name:g.name,thumbnail:g.thumbnail,nativeName:g.nativeName,englishName:g.englishName,genres:g.genres?JSON.stringify(g.genres.map(p=>p.name)):void 0,status:g.status,episodeCount:g.episodeCount!=null?Number(g.episodeCount):void 0,type:g.type,anilistId:g.anilistId})}catch(p){U.warn({err:p,provider:a,showId:i},"[Video] AniList metadata lookup failed while resolving numeric showId")}if(f){let p=g?.names?.romaji,m=g?.names?.native,I=g?.names?.synonyms;if(!p||!m)try{let w=await bi(i);p=p||w?.names?.romaji,m=m||w?.names?.native,I=I||w?.names?.synonyms}catch{}let C=[f,p,m,...(I??[]).slice(0,2)].filter(w=>!!w&&w.trim().length>0),B=[...new Set(C.map(w=>w.trim()))].filter((w,R,N)=>N.findIndex(T=>T.toLowerCase()===w.toLowerCase())===R),Q=null;for(let w of B){try{Q=await n[a]?.resolveShowId?.(w,p,t.mode)??null}catch(R){if(R.message==="AUTH_REQUIRED")throw R;Q=null}if(Q)break}if(Q)i=Q;else{U.warn({provider:a,showId:i,title:f,romaji:p},"[Video] resolveShowId failed, attempting fallback provider search");try{let w=await n[a]?.search?.({query:f}),R=ac((w||[]).map(N=>({title:N.name||N.englishName||"",id:N.id||N._id||""})),B);if(R)i=R.item.id;else return U.warn({provider:a,showId:i,title:f},"[Video] fallback provider search returned no results"),[]}catch(w){if(w.message==="AUTH_REQUIRED")throw w;return U.error({err:w,provider:a,showId:i,title:f},"[Video] fallback provider search failed"),[]}}}else return U.warn({provider:a,showId:i},"[Video] numeric showId passed to provider but local meta missing title"),[]}let l=EQe(e,t.provider);return l?await l.getStreamUrls(i,t.episodeNumber,t.mode)||[]:[]}catch(i){if(i.message==="AUTH_REQUIRED")throw Fc(i.provider||t.provider||"animepahe");return U.error({err:i,provider:t.provider},"Provider video fetch failed"),[]}})});var BQe=VBe(mQe,CQe,IQe);var yQe=new So({ttlSeconds:3600,maxKeys:2e3}),QQe=new So({ttlSeconds:3600,maxKeys:2e3});async function bQe(e){let t=e.trim().toLowerCase();if(!t)return null;let r=QQe.get(t);if(r!==void 0)return r;try{let n=new URLSearchParams({title:e.trim(),limit:"5","includes[]":"cover_art","order[relevance]":"desc"});for(let u of["safe","suggestive","erotica","pornographic"])n.append("contentRating[]",u);let i=await fetch(`https://api.mangadex.org/manga?${n.toString()}`,{headers:{"User-Agent":"Dango/3.0",Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!i.ok)return null;let s=await Vt(i),o=[];for(let u of s.data||[]){let c=u.relationships?.find(f=>f.type==="cover_art")?.attributes?.fileName;if(!c)continue;let l=`https://uploads.mangadex.org/covers/${u.id}/${c}.256.jpg`,d=u.attributes?.title,h=d?.en||d?.["ja-ro"]||Object.values(d||{})[0];h&&o.push({title:h,cover:l});for(let f of u.attributes?.altTitles||[]){let g=Object.values(f)[0];g&&o.push({title:g,cover:l})}}let a=ac(o,[e]),A=a?a.item.cover:null;return QQe.set(t,A),A}catch(n){return U.warn({err:n,title:e},"The MangaDex cover lookup failed"),null}}async function wQe(e){let t=String(e).trim().toUpperCase();if(!/^RJ\d{5,}$/.test(t))return null;let r=yQe.get(t);if(r!==void 0)return r;try{let n=await fetch(`https://www.dlsite.com/maniax/product/info/ajax?product_id=${t}`,{headers:{"User-Agent":"Mozilla/5.0",Accept:"application/json"},signal:AbortSignal.timeout(5e3)});if(!n.ok)return null;let s=await Vt(n),a=s[t]??s,A=typeof a?.work_image=="string"?a.work_image:void 0;if(!A)return null;let u=A.startsWith("//")?`https:${A}`:A;return yQe.set(t,u),u}catch(n){return U.warn({err:n,rjCode:t},"The DLsite poster lookup failed"),null}}zd();function oG(e){return e?e.slice(0,8)+"..."+e.slice(-4):"none"}var rQ=U.child({module:"DiscordGatewayRoutes"});function aG(e){let t=String(e||"");if(t.includes("/api/proxy")||t.includes("/api/image-proxy")){let r=t.match(/url=([^&]+)/);if(r)try{t=decodeURIComponent(r[1])}catch(n){return rQ.warn({err:n,thumb:t},"The proxy thumbnail url is not decodable"),""}}return!t.startsWith("https://")||t.includes("localhost")||t.includes("127.0.0.1")?"":t}var AG=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={};for(let o of["sessionId","title","thumbnail","trackLabel","chapterLabel","episodeLabel","rjCode"]){let a=le(t,o);a!==void 0&&(r[o]=a)}let n=t.thumbnails;Array.isArray(n)&&(r.thumbnails=n.map(String).filter(Boolean)),typeof t.isPlaying=="boolean"&&(r.isPlaying=t.isPlaying),typeof t.isAdult=="boolean"&&(r.isAdult=t.isAdult);let i=Ls(t,"currentTime");i!==void 0&&(r.currentTime=i);let s=Ls(t,"duration");return s!==void 0&&(r.duration=s),r}),B0t=()=>pe(e=>{if(e==null)return{};let t=le(ye(e),"page");return t===void 0?{}:{page:t}}),SQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"sessionId");return n!==void 0&&(r.sessionId=n),typeof t.bye=="boolean"&&(r.bye=t.bye),r}),y0t={asmr:{provider:"ASMR",labelField:"trackLabel",fallbackTitle:"ASMR",playingByDefault:!1,state:()=>""},manga:{provider:"Manga",labelField:"chapterLabel",fallbackTitle:"Manga",playingByDefault:!0,state:e=>e?`Reading ${e}`:"Reading"},tv:{provider:"TV",labelField:"episodeLabel",fallbackTitle:"TV",playingByDefault:!1,state:e=>e||"Movie"}};async function Q0t(e,t){let r=e.thumbnail||"";if(t==="asmr"){let n=r;if((!n||n.includes("weeabo0.xyz")||n.includes("japaneseasmr.com"))&&e.rjCode){let s=await wQe(e.rjCode);s&&(n=s)}return(n.includes("/api/image-proxy")||n.includes("weeabo0.xyz"))&&(n=""),{thumb:n,thumbs:e.thumbnails?.filter(Boolean)}}if(t==="manga"){let n=aG(r),i=e.thumbnails?.map(aG).filter(Boolean);if(!n&&e.title){let s=await bQe(e.title);if(s)return{thumb:s,thumbs:[s,...i||[]]}}return{thumb:n,thumbs:i}}return{thumb:aG(r)}}async function uG(e,t,r){if(!e.isServiceEnabled)return;t.sessionId&&e.heartbeat(t.sessionId);let n=y0t[r],i=t[n.labelField]||"",{thumb:s,thumbs:o}=await Q0t(t,r),a=r!=="manga";e.updatePresence({title:(t.title||n.fallbackTitle).slice(0,128),episode:i.slice(0,64),totalEpisodes:"",stateLine:n.state(i).slice(0,64),currentTime:a&&t.currentTime||0,duration:a&&t.duration||0,thumbnail:s,thumbnails:o,isPlaying:t.isPlaying===void 0?n.playingByDefault:t.isPlaying,providerName:n.provider,sessionId:t.sessionId,isAdult:t.isAdult===!0})}var TQe=At({pageStatus:ee.input(B0t()).mutation(async({ctx:e,input:t})=>!t.page||!e.discordRPC.isServiceEnabled?{success:!0}:(e.discordRPC.setIdleStatus(t.page),{success:!0})),heartbeat:ee.input(SQe()).mutation(async({ctx:e,input:t})=>!t.sessionId||!e.discordRPC.isServiceEnabled?{success:!0}:(t.bye?e.discordRPC.removeHeartbeat(t.sessionId):e.discordRPC.heartbeat(t.sessionId),{success:!0})),clear:ee.input(SQe()).mutation(async({ctx:e,input:t})=>e.discordRPC.isServiceEnabled?(e.discordRPC.clearPresence(t.sessionId),{success:!0}):{success:!0}),asmrPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"asmr"),{success:!0})),mangaPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"manga"),{success:!0})),tvPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"tv"),{success:!0})),gatewayStatus:ee.query(()=>{let e=Hr.hasToken();return{hasToken:e,masked:e?oG(process.env.DISCORD_GATEWAY_TOKEN):null,enabled:Hr.serviceEnabled}}),gatewaySave:ee.input(pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"token");return n!==void 0&&(r.token=n),r})).mutation(async({input:e})=>{let t=(e.token||"").trim();if(t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1)),t.length<30)throw it("Token too short");try{return await Rn({DISCORD_GATEWAY_TOKEN:t}),Hr.reloadToken(),rQ.info(`Discord Gateway token saved ${oG(t)} (not logged)`),{ok:!0,masked:oG(t)}}catch(r){throw rQ.error({err:r},"Failed to save Discord Gateway token"),yr("Failed to save token")}}),gatewayRemove:ee.mutation(async()=>{try{return await Rn({DISCORD_GATEWAY_TOKEN:""}),Hr.reloadToken(),rQ.info("Discord Gateway token removed"),{ok:!0}}catch(e){throw rQ.error({err:e},"Failed to remove Discord Gateway token"),yr("Failed to remove token")}})});var DQe=At({settings:cye,queue:hye,watchlist:pye,progress:Cye,notifications:Bye,continueWatching:Qye,discovery:xye,mangaLibrary:vye,mangaProgress:kye,asmrLibrary:Mye,asmrProgress:Fye,tvLibrary:Oye,tvProgress:Pye,tv:Hye,manga:qye,asmr:Wye,tracker:Kye,insights:rQe,auth:nQe,data:BQe,discord:TQe});function NQe(e,t,r){return{...e,lanAuthed:!Sd()||Uy(Jp(t,r))}}var b0t=new wd({isArray:e=>e==="manga",parseTagValue:!1,trimValues:!0});function px(e){return Array.isArray(e)?String(e[0]??""):String(e??"")}function w0t(e){switch(e){case"Plan to Read":return"Planned";case"On Hold":return"On-Hold";case"Reading":case"Completed":case"Dropped":return e;default:return"Planned"}}function S0t(e){try{return DQ(e).remote.address}catch{return e.req.header("x-dango-client-ip")??void 0}}var xQe="x-dango-not-ready";function fm(e,t){return e.header(xQe,"1"),typeof t=="string"?e.text(t,503):e.json(t,503)}async function T0t(e,t){let r=process.hrtime.bigint(),n=new URL(e.req.url),i=`${n.pathname}${n.search}`;await t();let s=Math.round(Number(process.hrtime.bigint()-r)/1e6*10)/10,o=e.res.status,a={method:e.req.method,url:i,status:o,ms:s};o>=500&&!e.res.headers.get(xQe)?U.warn(a,"request failed"):i.startsWith("/api/proxy")||U.trace(`${e.req.method} ${i} ${o} ${s}ms`)}async function D0t(e,t){let r=new Map,n=e.req.header("x-animepahe-ua");n&&r.set("ua",n);let i=e.req.header("x-animepahe-cookie");i&&r.set("cookie",i);let s=e.req.header("x-jasmr-ua");s&&r.set("jasmr_ua",s);let o=e.req.header("x-jasmr-cookie");return o&&r.set("jasmr_cookie",o),aT.run(r,()=>t())}async function N0t(e,t,r){let n;try{n=JSON.parse(r.toString("utf-8"))}catch{return e.json({error:"Invalid backup file."},400)}let i=n?.databases;if(!i||typeof i!="object")return e.json({error:"Invalid backup file: missing databases."},400);let s={anime:t.db,manga:t.mangaDb,tv:t.tvDb,asmr:t.asmrDb},a=Object.keys(ei).map(c=>({key:c,db:s[c],tables:bn[c].tables,libraryTables:bn[c].libraryTables,backupName:bn[c].backupName,setVersion:l=>Hb(c,l)})).filter(c=>i[c.key]!==void 0);if(a.length===0)return e.json({error:"Invalid backup file: no databases found."},400);let A=new Map;try{for(let c of a)A.set(c.key,nl(i[c.key],c.tables,`backup ${c.key}`))}catch(c){return U.warn({err:c},"Multi-database restore rejected: invalid payload"),e.json({error:"Invalid backup file."},400)}let u=[];try{for(let c of a){let l=A.get(c.key);l&&(il(c.db,c.tables,l,{libraryTables:c.libraryTables,backupName:c.backupName}),await c.setVersion(xa(l)),u.push(c.key))}}catch(c){return U.error({err:c,restored:u},"Multi-database restore failed partway"),e.json({error:"Restore failed partway.",restored:u},500)}return U.warn({restored:u},"Databases restored from backup file by user request"),e.json({success:!0,message:"Databases restored.",restored:u})}function R0t(e,t,r,n){let i=ae.IS_DEV?ae.DB_NAME_DEV:ae.DB_NAME_PROD,s=RQe.join(ae.ROOT,"restore_temp.db"),o=RQe.join(ae.ROOT,i);try{hm.writeFileSync(s,r)}catch(A){return U.error({err:A},"Failed to stage legacy database restore file"),Promise.resolve(e.json({error:"Failed to stage restore file."},500))}let a=t.db;return new Promise(A=>{a.close(u=>{if(u){A(e.json({error:"Failed to close database."},500));return}try{a.checkpoint()}catch(c){U.warn({err:c},"WAL checkpoint failed")}try{hm.existsSync(`${o}-wal`)&&hm.unlinkSync(`${o}-wal`),hm.existsSync(`${o}-shm`)&&hm.unlinkSync(`${o}-shm`)}catch(c){U.warn({err:c},"Failed to clean up WAL files")}hm.rename(s,o,async c=>{if(c){try{n.setDb(await n.initializeDatabase(o))}catch(l){U.error({err:l},"Failed to reopen DB after rename failure")}A(e.json({error:"Failed to replace database file."},500));return}try{n.setDb(await n.initializeDatabase(o)),A(e.json({success:!0,message:"Database restored."}))}catch(l){U.error({err:l},"Failed to initialize restored database"),A(e.json({error:"Failed to initialize restored database."},500))}})})})}function vQe(e,t,r,n,i,s,o){let a=new Y6;a.use(T0t),a.use(D0t),a.get("/api/health",u=>{let c=e();return c.shuttingDown?fm(u,{status:"shutting-down",ready:!1}):c.dbReady?u.json({status:"ok",ready:!0}):fm(u,{status:"starting",ready:!1})}),a.use(async(u,c)=>{let l=t();if(l.shuttingDown)return fm(u,"Server is shutting down...");if(!l.dbsReady)return fm(u,"Database initializing...");if(l.bootSyncing&&u.req.method!=="GET"&&u.req.method!=="HEAD"&&u.req.method!=="OPTIONS")return fm(u,"Sync in progress...");await c()});let A=jIe({threshold:1024});return a.use(async(u,c)=>{if(u.req.header("x-no-compression")){await c();return}await A(u,c)}),a.use(async(u,c)=>{let l=u.req.header("origin");if(u.req.method==="OPTIONS"){if(!l||!Ly(l)){await c();return}let d=u.req.header("access-control-request-headers");return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":l,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Methods":"GET,HEAD,PUT,PATCH,POST,DELETE",...d?{"Access-Control-Allow-Headers":d}:{},Vary:"Origin"}})}(!l||Ly(l))&&(l&&u.header("Access-Control-Allow-Origin",l),u.header("Access-Control-Allow-Credentials","true"),u.header("Vary","Origin")),await c()}),a.use(async(u,c)=>{let l=u.req.method.toUpperCase();if(!["POST","PUT","DELETE","PATCH"].includes(l)){await c();return}if(u.req.header("sec-fetch-site")==="cross-site"){let f=u.req.header("origin");if(!Ly(f))return u.json({error:"Forbidden: cross-site request rejected"},403)}let h=u.req.header("origin");if(h&&!Ly(h))return u.json({error:"Forbidden: cross-origin request rejected"},403);await c()}),a.get("/api/auth/app-status",u=>{let c=!Sd()||Uy(Jp(u.req.header("authorization"),u.req.header("cookie")));return u.json({hasPassword:Sd(),isAuthenticated:c,port:ae.PORT})}),a.post("/api/auth/app-login",async u=>{let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");if(!Sd())return u.json({success:!0});if(!l)return u.json({error:"Password required"},400);if(!ICe(l))return u.json({error:"Invalid password"},401);let d=BCe();return u.header("Set-Cookie",wCe(d.token,d.expiry)),u.json({success:!0})}),a.post("/api/auth/app-logout",u=>(yCe(Jp(u.req.header("authorization"),u.req.header("cookie"))),u.header("Set-Cookie",SCe()),u.json({success:!0}))),a.post("/api/auth/app-setup",async u=>{if(!f5(u.req.header("x-dango-client-ip")))return u.json({error:"Forbidden"},403);let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");try{return await CCe(l),QCe(),u.json({success:!0,hasPassword:Sd()})}catch{return u.json({error:"Failed to update password"},500)}}),a.use(async(u,c)=>{let l=u.req.path;if(!l.startsWith("/api/")){await c();return}if(bCe.has(l)){await c();return}if(l.startsWith("/api/internal/")&&f5(S0t(u))){await c();return}if(!Sd()){await c();return}if(Uy(Jp(u.req.header("authorization"),u.req.header("cookie")))){await c();return}return u.json({error:"LAN_AUTH_REQUIRED"},401)}),a.all("/api/trpc/*",u=>kBe({endpoint:"/api/trpc",req:u.req.raw,router:DQe,createContext:()=>NQe({...r(),apiCache:o.getApiCache(),getTvProvider:o.getTvProvider,getMangaProvider:o.getMangaProvider,getJasmr:o.getJasmr,getProviders:o.getProviders,getCatalog:i.getCatalog,discordRPC:Qy,offlineDb:pn,malCacheStore:Ur},u.req.header("authorization"),u.req.header("cookie"))})),a.post("/api/import/mal-xml",async u=>{let c=r(),l=await u.req.parseBody().catch(()=>({})),d=l.xmlfile,h=d instanceof File?Buffer.from(await d.arrayBuffer()):void 0,f=qCe(h,{erase:l.erase,useOfflineDb:l.useOfflineDb,skipFallback:l.skipFallback});if(!f.ok)return u.json(f.body,f.status);let g=new TransformStream,p=g.writable.getWriter(),m=new TextEncoder,I=!1;u.req.raw.signal.addEventListener("abort",()=>{I=!0},{once:!0});let C=(B,Q)=>{I||p.write(m.encode(`event: ${B}
985
+ LEFT JOIN shows_meta sm ON sm.id = w.id`),getAllAnilistIds:e=>te(e).all(y`SELECT anilistId FROM shows_meta WHERE anilistId IS NOT NULL`)};function Xye(e,t,r){if(!e)return[];try{return e.startsWith("[")?JSON.parse(e):e.split(",").map(n=>n.trim())}catch(n){return U.warn({err:n,showId:t},`Failed to parse genres for ${r}`),[]}}async function zye(e){let[t,r,n,i,s,o,a,A]=await Promise.all([Ms.getCoreStats(e),Ms.getActivityGrid(e),Ms.getHourlyDist(e),Ms.getSeasonality(e),Ms.getAllWatches(e),Ms.getWatchedShowsMeta(e),Ms.getDroppedShows(e),Ms.getCompletionVelocities(e)]),u=r.length>0?Math.max(...r.map(C=>C.count)):0,c=[];if(s.length>0){let C=s[0].effectiveSeconds??s[0].currentTime;for(let B=1;B<s.length;B++){let Q=new Date(s[B-1].watchedAt).getTime(),R=new Date(s[B].watchedAt).getTime()-Q;Number.isFinite(R)&&R>0&&R<36e5?C+=s[B].effectiveSeconds??s[B].currentTime:(c.push(C),C=s[B].effectiveSeconds??s[B].currentTime)}c.push(C)}let l=c.length>0?Math.round(c.reduce((C,B)=>C+B,0)/c.length/60):0,d={},h=0,f=0;for(let C of o){let B=Xye(C.genres,C.id,"insights");for(let Q of B)d[Q]=(d[Q]||0)+1;if(C.popularityScore){let Q=C.popularityScore;Q>10&&(Q=Q/10),h+=Q,f++}}let g=Object.entries(d).sort((C,B)=>B[1]-C[1])[0]?.[0],m={Action:"Shonen Warrior",Romance:"Hopeless Romantic",Comedy:"Chaos Enjoyer","Slice of Life":"Vibe Seeker",Horror:"Fearless Watcher",Fantasy:"Isekai Traveller","Sci-Fi":"Future Scientist",Drama:"Feels Collector"}[g||""]||"Anime Enthusiast",I=A.length>0?Math.round(A.reduce((C,B)=>C+B.daysToFinish,0)/A.length):0;return{totalHours:Math.round((t?.totalSeconds||0)/3600),totalEpisodes:t?.totalEpisodes||0,totalAnime:t?.totalAnime||0,completedAnime:t?.completedCount||0,completionRate:t?.totalWatchlist>0?Math.round(t.completedCount/t.totalWatchlist*100):0,persona:m,bingeFactor:u,avgSessionMinutes:l,avgCompletionDays:I,popularityScore:f>0?Math.round(h/f):0,genreSplit:Object.entries(d).map(([C,B])=>({name:C,count:B})).sort((C,B)=>B.count-C.count).slice(0,8)||[],activityGrid:r||[],hourlyDist:Array.from({length:24},(C,B)=>{let Q=B.toString().padStart(2,"0");return{hour:Q,count:n?.find(w=>w.hour===Q)?.count||0}})||[],seasonality:Array.from({length:12},(C,B)=>{let Q=(B+1).toString().padStart(2,"0");return{month:Q,seconds:i?.find(w=>w.month===Q)?.seconds||0}})||[],droppedShows:(a||[]).slice(0,5)}}async function Zye(e){let t=await Ms.getWatchedEpisodesWithMeta(e),r={};for(let i of t){let s=Xye(i.genres,i.showId,"genre cards"),o=(i.effectiveSeconds??i.currentTime)||0,a=i.popularityScore||0;a>10&&(a=a/10);for(let A of s)r[A]||(r[A]={count:0,totalTime:0,scores:[],showWatches:{},showMeta:{}}),r[A].count++,r[A].totalTime+=o,a>0&&r[A].scores.push(a),r[A].showWatches[i.showId]=(r[A].showWatches[i.showId]||0)+1,(i.name||i.thumbnail)&&(r[A].showMeta[i.showId]={name:i.name,nativeName:i.nativeName,englishName:i.englishName,thumbnail:i.thumbnail})}let n=Object.entries(r).map(([i,s])=>{let o=Object.entries(s.showWatches).sort((a,A)=>A[1]-a[1]).slice(0,4).map(([a])=>({id:a,name:s.showMeta[a]?.name||"",nativeName:s.showMeta[a]?.nativeName,englishName:s.showMeta[a]?.englishName,thumbnail:s.showMeta[a]?.thumbnail||""}));return{rank:0,name:i,count:s.count,meanScore:s.scores.length>0?s.scores.reduce((a,A)=>a+A,0)/s.scores.length:0,timeWatched:s0t(s.totalTime),topShows:o}});return n.sort((i,s)=>s.count-i.count),n.forEach((i,s)=>{i.rank=s+1}),n}function s0t(e){let t=Math.floor(e/86400),r=Math.floor(e%86400/3600),n=Math.floor(e%3600/60);return t>0?`${t} days ${r>0?`${r} hours`:""}`:r>0?`${r} hours${n>0?` ${n} mins`:""}`:`${n} mins`}function eQe(e){if(!e)return[];try{if(e.startsWith("[")){let t=JSON.parse(e);return Array.isArray(t)?t.map(String):[]}return e.split(",").map(t=>t.trim()).filter(Boolean)}catch{return[]}}async function o0t(e){let[t,r,n]=await Promise.all([Ms.getLibraryShowsWithGenres(e),Ms.getAllAnilistIds(e),Ms.getWatchedEpisodesWithMeta(e)]),i={},s={};for(let c of t){let l=eQe(c.genres);if(c.status==="Completed")for(let d of l)i[d]=(i[d]||0)+1;else if(c.status==="Dropped")for(let d of l)s[d]=(s[d]||0)+1}let o={};for(let c of n){let l=c.englishName||c.name||c.showId;for(let d of eQe(c.genres)){o[d]||(o[d]=new Map);let h=o[d].get(c.showId)||{title:l,count:0};h.count+=1,o[d].set(c.showId,h)}}let a={},A=Object.entries(i).sort((c,l)=>l[1]-c[1]).slice(0,6);for(let[c]of A)a[c]=[...o[c]?.values()||[]].sort((l,d)=>d.count-l.count).slice(0,2).map(l=>l.title);let u=new Set;for(let c of t)/^\d+$/.test(c.id)&&u.add(Number(c.id));for(let c of r)c.anilistId&&u.add(c.anilistId);return{genreComp:i,genreDrop:s,exemplars:a,knownIds:[...u]}}var a0t="id title { romaji english } coverImage { large } averageScore popularity episodes seasonYear format genres isAdult status";function A0t(e,t){let r=Math.max(1,...Object.values(e)),n={};for(let[i,s]of Object.entries(e)){let o=t[i]||0;n[i]=s/r*(s/(s+o))}return n}function u0t(e){let t=Object.entries(e).sort((i,s)=>s[1]-i[1]).slice(0,4).map(([i])=>i);for(;t.length<2;)t.push("Fantasy");let r=[[t[0],t[1]],[t[0],t[2]||t[1]],[t[1],t[2]||t[0]],[t[0],t[3]||t[1]]],n=new Set;return r.filter(i=>{let s=[...i].sort().join("|");return n.has(s)?!1:(n.add(s),!0)})}function c0t(e,t,r=2){let n=new Map;for(let i of t)for(let s of e[i]||[])n.set(s,(n.get(s)||0)+1);return[...n.entries()].sort((i,s)=>s[1]-i[1]).slice(0,r).map(([i])=>i)}async function l0t(e){let t=new Set(e.knownIds||[]);if(t.size===0)return[];let r=A0t(e.genreComp,e.genreDrop),n=.15,i=Object.values(r).reduce((u,c)=>u+c,0)||1,s=new Map;for(let u of u0t(r))try{let c=await rr(`query ($g: [String]) { Page(page: 1, perPage: 20) { media(genre_in: $g, type: ANIME, status: FINISHED, isAdult: false, averageScore_greater: 68, sort: SCORE_DESC) { ${a0t} } } }`,{g:u});for(let l of c?.data?.Page?.media||[])s.has(l.id)||s.set(l.id,l)}catch{}if(s.size===0)return[];let o=[];for(let u of s.values()){if(t.has(u.id)||u.isAdult||u.format==="MUSIC"||u.format==="SPECIAL")continue;let c=u.genres||[],d=.65*(c.reduce((h,f)=>h+(r[f]??n),0)/i)+.25*((u.averageScore||70)/100)+.1*Math.min(1,(u.popularity||0)/2e5);o.push({m:u,score:d,overlap:c.filter(h=>(r[h]??0)>.3)})}o.sort((u,c)=>c.score-u.score);let a=o.slice(0,15),A=new Map;try{let u=await rr("query ($ids: [Int]) { Page(page: 1, perPage: 50) { media(id_in: $ids, type: ANIME) { id relations { edges { relationType node { id title { romaji english } type } } } } } }",{ids:a.map(c=>c.m.id)});for(let c of u?.data?.Page?.media||[])A.set(c.id,c)}catch{}return a.map(u=>{let l=A.get(u.m.id)?.relations?.edges?.find(m=>m.relationType==="PREQUEL"&&m.node?.type==="ANIME")?.node,d=u.score,h="entry",f=null;l&&l.id&&!t.has(l.id)?(h="sequel",f=l.title?.english||l.title?.romaji||null,d-=.3):l&&(h="continue",d+=.05);let g=u.m.genres||[],p=u.m.title?.english||u.m.title?.romaji||"Unknown";return{id:u.m.id,title:p,url:`https://anilist.co/anime/${u.m.id}`,cover:u.m.coverImage?.large||null,year:u.m.seasonYear??null,format:u.m.format||"TV",episodes:u.m.episodes??null,averageScore:u.m.averageScore??null,genres:g,matchPct:Math.round(d*100),sharedGenres:u.overlap,exemplars:c0t(e.exemplars,g),kind:h,prequelTitle:f}})}var Ex=null;function d0t(e){return JSON.stringify([e.genreComp,e.genreDrop,e.knownIds.length])}async function h0t(e,t){if(!Ex||Ex.hash!==t)try{let r=await l0t(e);r.length>0&&(Ex={hash:t,candidates:r})}catch(r){U.warn({err:r?.message},"Recommendation candidates failed, reusing previous")}return Ex?.candidates||[]}async function tQe(e){let t=await o0t(e);return h0t(t,d0t(t))}var rQe=At({summary:ee.query(async({ctx:e})=>zye(e.db)),genreCards:ee.query(async({ctx:e})=>Zye(e.db)),recommendations:ee.query(async({ctx:e})=>({candidates:await tQe(e.db)}))});Nn();zd();async function iG(e,t,r){let n=ae.IS_DEV?ae.REMOTE_FOLDER_DEV:ae.REMOTE_FOLDER_PROD;await Yb({db:t,mangaDb:e.mangaDb,tvDb:e.tvDb,asmrDb:e.asmrDb},{remoteFolder:n,preferredProvider:r})}var f0t=()=>pe(e=>{let t=ye(e);return{clientId:t.clientId,clientSecret:t.clientSecret,workerUrl:t.workerUrl}}),g0t=()=>pe(e=>{let t=ye(e);if(typeof t.clientId!="string")throw it("clientId required");return{clientId:t.clientId}}),E0t=()=>pe(e=>({provider:ye(e).provider})),p0t=()=>pe(e=>({remote:ye(e).remote})),m0t=()=>pe(e=>({port:ye(e).port})),nQe=At({configStatus:ee.query(async()=>{let e=!!ae.GOOGLE_AUTH_WORKER_URL,t=!!process.env.GOOGLE_CLIENT_ID&&!!process.env.GOOGLE_CLIENT_SECRET;return{hasConfig:e||t,useWorker:e}}),googleAuth:ee.query(async()=>({useWorker:!!ae.GOOGLE_AUTH_WORKER_URL,hasCustomWorkerUrl:!!process.env.GOOGLE_AUTH_WORKER_URL,hasCustomClientId:!!process.env.GOOGLE_CLIENT_ID,hasClientSecret:!!process.env.GOOGLE_CLIENT_SECRET})),saveGoogleAuth:ee.input(f0t()).mutation(async({input:e})=>{let{clientId:t,clientSecret:r,workerUrl:n}=e,i={};return typeof t=="string"&&(i.GOOGLE_CLIENT_ID=t),typeof r=="string"&&(i.GOOGLE_CLIENT_SECRET=r),typeof n=="string"&&(i.GOOGLE_AUTH_WORKER_URL=n),await Rn(i),typeof n=="string"&&(ae.GOOGLE_AUTH_WORKER_URL=n),typeof t=="string"&&(ae.GOOGLE_CLIENT_ID=t||void 0),typeof r=="string"&&(ae.GOOGLE_CLIENT_SECRET=r||void 0),await Jg(),{success:!0}}),saveGithubAuth:ee.input(g0t()).mutation(async({input:e})=>(await Rn({GITHUB_CLIENT_ID:e.clientId}),{success:!0})),rcloneSettings:ee.query(async()=>{let e=await Ui.listRemotes();return{remote:ae.RCLONE_REMOTE||"",availableRemotes:e,activeRemote:Ui.isActive()?Ui.getRemoteName():null}}),syncSettings:ee.query(async()=>({activeProvider:process.env.SYNC_PROVIDER||"default",actualActiveProvider:j2(),authenticatedProviders:{github:as.isAuthenticated(),google:Fi.isAuthenticated(),rclone:Ui.isActive()}})),saveSyncProvider:ee.input(E0t()).mutation(async({input:e})=>{let{provider:t}=e;return await Rn({SYNC_PROVIDER:t==="default"?"":t}),await Jg(),{success:!0,activeProvider:process.env.SYNC_PROVIDER||"default"}}),githubStatus:ee.query(async()=>{try{let e=await as.getUserProfile();return{authenticated:!!e,user:e,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}catch(e){return U.error({err:e},"Failed to fetch GitHub auth status"),{authenticated:!1,user:null,device:as.getDeviceState(),hasCustomClientId:!!process.env.GITHUB_CLIENT_ID}}}),githubStart:ee.mutation(async({ctx:e})=>await as.startDeviceAuth(e.db,(r,n)=>iG(e,r,n))),githubPoll:ee.query(async()=>as.getDeviceState()),githubLogout:ee.mutation(async()=>(await as.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0})),saveRclone:ee.input(p0t()).mutation(async({ctx:e,input:t})=>{let{remote:r}=t;return await Rn({RCLONE_REMOTE:r,SYNC_PROVIDER:"rclone"}),await iG(e,e.db,"rclone"),{success:!0}}),setServerPort:ee.input(m0t()).mutation(async({input:e})=>{let t=Number(e.port);if(!Number.isInteger(t)||t<1||t>65535)throw it("Port must be an integer between 1 and 65535");return await Rn({PORT:String(t)}),U.info({port:t},"Server port saved. Restart required to apply."),{success:!0,port:t}}),googleLogin:ee.mutation(async({ctx:e})=>{if(Fi.isAuthenticated()){if(await Fi.getUserProfile())return await Rn({SYNC_PROVIDER:"google"}),await iG(e,e.db,"google"),{url:null,authenticated:!0};U.warn("Google tokens found but invalid. Clearing and requesting new auth."),await Fi.logout()}return{url:await Fi.getAuthUrl(),authenticated:!1}}),user:ee.query(async()=>await Fi.getUserProfile()),logout:ee.mutation(async()=>(await Fi.logout(),await Rn({SYNC_PROVIDER:""}),await Jg(),{success:!0}))});var iQe=()=>pe(e=>{let t=ye(e),r={date:gt(t,"date")},n=le(t,"format");return n!==void 0&&(r.format=n),r}),sQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"format");return n!==void 0&&(r.format=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,12,50,"size")),r}),oQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"query");n!==void 0&&(r.query=n),t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let i=le(t,"sortBy");i!==void 0&&(r.sortBy=i);let s=le(t,"type");s!==void 0&&(r.type=s);let o=le(t,"status");o!==void 0&&(r.status=o);let a=le(t,"season");a!==void 0&&(r.season=a);let A=Ls(t,"year");A!==void 0&&(r.year=A);let u=le(t,"country");u!==void 0&&(r.country=u);let c=le(t,"genres");c!==void 0&&(r.genres=c);let l=le(t,"excludeGenres");l!==void 0&&(r.excludeGenres=l);let d=le(t,"excludeTags");d!==void 0&&(r.excludeTags=d);let h=Ls(t,"minScore");h!==void 0&&(r.minScore=h);let f=Ls(t,"minEpisodes");f!==void 0&&(r.minEpisodes=f);let g=le(t,"adult");return g!==void 0&&(r.adult=g),r}),aQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"title");return n!==void 0&&(r.title=n),r}),AQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");return i!==void 0&&(r.episodeNumber=i),r}),uQe=()=>pe(e=>{let t=ye(e),r={};t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,14,50,"size"));let n=le(t,"format");return n!==void 0&&(r.format=n),r}),cQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"sort");return n!==void 0&&(r.sort=n),t.page!==void 0&&(r.page=Ri(t)),t.size!==void 0&&(r.size=Xi(t,20,50,"size")),r}),lQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"mode");(i==="sub"||i==="dub")&&(r.mode=i);let s=le(t,"provider");return s!==void 0&&(r.provider=s),r}),dQe=()=>pe(e=>({id:gt(ye(e),"id")})),hQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"showId");n!==void 0&&(r.showId=n);let i=le(t,"episodeNumber");i!==void 0&&(r.episodeNumber=i);let s=le(t,"mode");(s==="sub"||s==="dub")&&(r.mode=s);let o=le(t,"provider");return o!==void 0&&(r.provider=o),r}),fQe=()=>pe(e=>{let t=ye(e),r={};for(let o of["provider","query","type","status","season","country","genres","genre","excludeGenres","sortBy","order","studio","blacklist"]){let a=le(t,o);a!==void 0&&(r[o]=a)}t.page!==void 0&&(r.page=Ri(t)),t.limit!==void 0&&(r.limit=Xi(t,14,50));let n=Ls(t,"year");n!==void 0&&(r.year=n);let i=Ls(t,"minScore");i!==void 0&&(r.minScore=i);let s=Ls(t,"minEpisodes");return s!==void 0&&(r.minEpisodes=s),r}),gQe=()=>pe(e=>{let t=ye(e),r={},n=le(t,"provider");n!==void 0&&(r.provider=n);let i=le(t,"nativeId");i!==void 0&&(r.nativeId=i);let s=le(t,"title");s!==void 0&&(r.title=s);let o=le(t,"thumbnail");return o!==void 0&&(r.thumbnail=o),r});function EQe(e,t){let r=t?.toLowerCase();return r&&e.getProviders()[r]||null}function _d(e,t){let r=(t||"").toLowerCase(),n=e.getProviders();if(!r||!n[r]||r==="mal"||r==="anilist")return!1;let i=pQe(e);return i?i.has(r):!0}function pQe(e){let t=e.getCatalog();return!t||t.length===0?null:new Set(t.filter(r=>r.mature&&(r.kind??"anime")==="anime"&&r.loaded).map(r=>r.id.toLowerCase()))}async function sG(e,t,r){let n=e.getProviders(),i=pQe(e),s=i?[...i]:Object.keys(n),o=[r,...s].filter(A=>!!A&&A!=="mal"&&A!=="anilist"&&!!n[A]),a=new Set;for(let A of o)if(!a.has(A)){a.add(A);try{let u=await n[A].resolveShowId?.(t);if(u)return{provider:n[A],nativeId:u}}catch{}}return null}function lm(e){if(typeof e!="string"||!e.trim())return;let t=e.split(",").map(r=>r.trim()).filter(Boolean);return t.length>0?t:void 0}var dm=e=>Array.isArray(e)&&e.length>0,mQe=At({schedule:ee.input(iQe()).query(async({ctx:e,input:t})=>{let r=t.date,n=t.format||"TV";return jn(e,`schedule-${r}-${n}`,1800,async()=>{try{let i=new Date(r+"T00:00:00.000Z"),s=n==="ADULT";return await kP(i,s?void 0:n,s)}catch(i){return U.error({err:i,date:r},"Schedule fetch failed"),[]}},dm)}),latestReleases:ee.input(sQe()).query(async({ctx:e,input:t})=>{let r=t.format||"TV",n=t.page||1,i=t.size||12;return jn(e,`latest-releases-${r}-${n}-${i}`,300,async()=>{try{return await NP(r,n,i)}catch(s){return U.error({err:s},"Latest releases fetch failed"),[]}},dm)}),search:ee.input(oQe()).query(async({ctx:e,input:t})=>{let r={};return t.query!==void 0&&(r.query=t.query),t.page!==void 0&&(r.page=String(t.page)),t.limit!==void 0&&(r.limit=String(t.limit)),t.sortBy!==void 0&&(r.sortBy=t.sortBy),t.type!==void 0&&(r.type=t.type),t.status!==void 0&&(r.status=t.status),t.season!==void 0&&(r.season=t.season),t.year!==void 0&&(r.year=String(t.year)),t.country!==void 0&&(r.country=t.country),t.genres!==void 0&&(r.genres=t.genres),t.excludeGenres!==void 0&&(r.excludeGenres=t.excludeGenres),t.excludeTags!==void 0&&(r.excludeTags=t.excludeTags),t.minScore!==void 0&&(r.minScore=String(t.minScore)),t.minEpisodes!==void 0&&(r.minEpisodes=String(t.minEpisodes)),t.adult!==void 0&&(r.adult=t.adult),jn(e,`search-${JSON.stringify(r)}`,1800,async()=>{try{return await pf({query:t.query||"",page:t.page||1,perPage:t.limit||14,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),tag_not_in:lm(t.excludeTags),averageScore_greater:t.minScore,episodes_greater:t.minEpisodes,isAdult:t.adult==="true"?!0:t.adult==="false"?!1:void 0,sort:t.sortBy})}catch(n){return U.error({err:n},"search failed"),[]}},dm)}),seasonal:ee.input(uQe()).query(async({ctx:e,input:t})=>{let r=t.page||1,n=t.size||14,i=t.format;return jn(e,`seasonal-${i||"ALL"}-${r}-${n}`,300,async()=>{try{return await RP(r,n,i)}catch(s){return U.error({err:s},"Seasonal fetch failed"),[]}},dm)}),popularList:ee.input(cQe()).query(async({ctx:e,input:t})=>{let r=t.sort==="POPULARITY_DESC"?"POPULARITY_DESC":"TRENDING_DESC",n=t.page||1,i=t.size||20;return jn(e,`popular-list-${t.sort||"TRENDING_DESC"}-${n}-${i}`,300,async()=>{try{return await xP(n,i,r)}catch(s){return U.error({err:s},"Popular list fetch failed"),[]}},dm)}),spotlight:ee.query(async({ctx:e})=>jn(e,"spotlight",300,async()=>{try{return await vP(1,20)}catch(t){return U.error({err:t},"Spotlight fetch failed"),[]}},dm)),genresAndTags:ee.query(async()=>{try{return await ZO()}catch(e){throw U.error({err:e},"genres-and-tags failed"),yr("Failed to load genres")}}),anilistStatus:ee.query(async()=>{let e=!Qi();return e||OC().catch(()=>{}),{available:e,wasDownAtBoot:cT()}}),systemNotifications:ee.query(async()=>{let e=[];return cT()&&Qi()&&e.push({id:"system-anilist-down",type:"system",title:"AniList API",message:"AniList metadata API is currently down. dango is experiencing degraded performance. MAL + Kitsu is being used as a fallback in the meantime. Some features may be limited until service is restored.",icon:"warning",createdAt:Date.now()}),e})});var I0t=e=>Array.isArray(e)&&e.length>0,IQe=At({matureResolve:ee.input(aQe()).query(async({ctx:e,input:t})=>jn(e,`mature-resolve-${t.title||""}`,3600,async()=>{try{let r=(t.title||"").trim();if(!r)throw it("title is required");let n=await ys(r);if(n){let s=n.id;return{id:typeof s=="number"&&s<0?`mal-${Math.abs(s)}`:s}}let i=await EP(e.malCacheStore(),r);if(i)return{id:i,provider:"mal"};throw Mc("No match found")}catch(r){throw r instanceof nt?r:(U.error({err:r},"mature resolve failed"),yr("Resolve failed"))}},I0t)),matureSearch:ee.input(fQe()).query(async({ctx:e,input:t})=>{let r=(t.provider||"anilist").toLowerCase();if(r!=="anilist"&&r!=="mal"&&!_d(e,r))throw it("Unknown mature provider");let n={};for(let[i,s]of Object.entries(t))s!==void 0&&(n[i]=String(s));return jn(e,`mature-search-${JSON.stringify(n)}`,600,async()=>{try{let i=t.query||"",s=t.page||1,o=t.limit||14;if(r==="anilist"){let a=await pf({query:i,page:s,perPage:o,format:t.type,status:t.status,season:t.season,seasonYear:t.year,countryOfOrigin:t.country,genre:t.genres,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy});return{data:a,hasMore:a.length>=o}}if(_d(e,r)){let a=e.getProviders()[r];if(a?.browse){let u=t.genre||t.genres||void 0,c=await a.browse({query:i,page:s,limit:o,pageSize:o,genre:u,genres:t.genres||u,order:t.order||t.sortBy||void 0,sort:t.sortBy||t.order||void 0,studio:t.studio||void 0,blacklist:t.blacklist||void 0});return{data:c.shows,hasMore:c.hasMore,...c.total!==void 0?{total:c.total}:{},...c.genres?{genres:c.genres}:{}}}return{data:(await a.search({query:i})).map(u=>({...u,isAdult:!0})),hasMore:!1}}if(r==="mal"){let a=[];try{a=await Kl(e.malCacheStore(),{query:i,page:s,perPage:50,format:t.type,status:t.status,genre:t.genres||void 0,genre_not_in:lm(t.excludeGenres),isAdult:!0,sort:t.sortBy,averageScore_greater:t.minScore,episodes_greater:t.minEpisodes})}catch(c){U.error({err:c},"mal mature search failed")}let A=a.map(c=>({...cr(c),isAdult:!0}));return{data:A.slice(0,o),hasMore:A.length>=o}}return{data:[],hasMore:!1}}catch(i){return U.error({err:i},"mature search failed"),{data:[],hasMore:!1}}},i=>!!i&&typeof i=="object"&&Array.isArray(i.data))}),matureFilters:ee.query(async({ctx:e})=>{try{let t=e.getCatalog()??[],r={};for(let n of t)!n.mature||(n.kind??"anime")!=="anime"||!n.loaded||(r[n.id]={label:n.label,...n.browse?{browse:n.browse}:{},...n.facets?.genres?.length?{genres:n.facets.genres}:{},...n.facets?.orders?.length?{orders:n.facets.orders}:{}});return{providers:r}}catch(t){throw U.error({err:t},"mature filters failed"),yr("Failed to load filters")}}),matureAllocate:ee.input(gQe()).mutation(async({ctx:e,input:t})=>{try{let r=String(t.provider||"").toLowerCase(),n=String(t.nativeId||"").trim(),i=String(t.title||"").trim(),s=String(t.thumbnail||"");if(!r||!_d(e,r))throw it("Unknown provider");if(!n||!i)throw it("nativeId and title are required");return{id:(await ko.allocate(e.db,{provider:r,nativeId:n,title:i,thumbnail:s})).id}}catch(r){throw r instanceof nt?r:(U.error({err:r},"temp show allocate failed"),yr("Allocate failed"))}})});var C0t=e=>Array.isArray(e)&&e.length>0,CQe=At({skipTimes:ee.input(AQe()).query(async({input:e})=>{let t=e.showId||"",r=e.episodeNumber||"";try{if(/^\d+$/.test(t)){let n=await Sr(`https://api.aniskip.com/v1/skip-times/${t}/${r}?types=op&types=ed`,{},{timeoutMs:1e4});if(n.ok)return await Vt(n)}return{found:!1,results:[]}}catch(n){return U.warn({err:n,showId:t,episodeNumber:r},"Skip-times fetch failed"),{found:!1,results:[]}}}),episodes:ee.input(lQe()).query(async({ctx:e,input:t})=>{let r=t.showId;return jn(e,`episodes-${r||""}`,3600,async()=>{let n=r;if(!n)return{episodes:[]};let i=e.db,s=e.getProviders(),o=await vr(i,n),a=jA(o);if(a)try{let l=await cc(a);l?.anilistId&&l.anilistId>0&&(o=String(l.anilistId))}catch{}if(vg(o)){try{let l=await ko.getById(i,o);if(!l||!_d(e,l.provider))return{episodes:[]};let d=String(t.provider||"").toLowerCase(),h=s[l.provider];if(h&&(!d||d===l.provider)){let g=await h.getEpisodes(l.nativeId,t.mode);return g?.episodes?.length?g:{episodes:[]}}let f=await sG(e,l.title,d);if(f){let g=await f.provider.getEpisodes(f.nativeId,t.mode);if(g?.episodes?.length)return g}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(String(t.provider||"animepahe"));U.warn({err:l,showId:o},"Temp show episodes fetch failed")}return{episodes:[]}}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))try{if(s.animepahe)return await s.animepahe.getEpisodes(o,t.mode)||{episodes:[]}}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc("animepahe");return U.warn({err:l,showId:o},"Animepahe episodes fetch failed"),{episodes:[]}}if(/^(mal-\d+|-?\d+)$/i.test(o)){let l=[];try{l=await KC(o)}catch(d){U.error({err:d,showId:o},"Episodes fetch failed")}if(l.length===0){let d=Math.abs(parseInt(o,10));if(!Number.isFinite(d))return{episodes:l};try{let f=(await $l(e.malCacheStore(),d)).detail?.episodes;f&&f>0&&f<=500&&(l=Array.from({length:f},(g,p)=>(p+1).toString()))}catch{}}if(l.length===0){let d=t.provider?.toLowerCase(),h=d?s[d]:void 0;if(h?.isDirectId?.(o))try{let f=await h.getEpisodes(o,t.mode);if(f?.episodes?.length)return f}catch(f){if(f.message==="AUTH_REQUIRED")throw Fc(d||"animepahe");U.warn({err:f,showId:o,provider:d},"Episodes fetch failed")}}return{episodes:l}}let u=t.provider?.toLowerCase(),c=u?s[u]:void 0;if(c)try{let l=await c.getEpisodes(o,t.mode);if(l?.episodes?.length)return l}catch(l){if(l.message==="AUTH_REQUIRED")throw Fc(u||"animepahe");U.warn({err:l,showId:o,provider:u},"Episodes fetch failed")}return{episodes:[]}},C0t)}),showMeta:ee.input(dQe()).query(async({ctx:e,input:t})=>{let r=t.id;return jn(e,`meta-${r}`,3600,async()=>{let n=e.db,i=await vr(n,r);if(vg(i)){let o=await ko.getById(n,i);return!o||!_d(e,o.provider)?{}:{_id:o.id,id:o.id,name:o.title,englishName:o.title,thumbnail:o.thumbnail||"",type:"TV",isAdult:!0,status:"UNKNOWN",provider:o.provider,nativeId:o.nativeId}}if(/^(mal-\d+|-?\d+)$/i.test(i)){let o=null;try{o=await bi(i)}catch(c){U.warn({err:c,id:i},"AniList show-meta fetch failed, trying local cache")}let a=await ct.getById(n,i);if(!o){if(!a)return{};if(typeof a.genres=="string")try{let c=JSON.parse(a.genres);a.genres=Array.isArray(c)?c.map(l=>({name:typeof l=="string"?l:String(l?.name??"")})):[]}catch{a.genres=[]}return a}!o.status&&a?.status&&(o.status=String(a.status)),!o.episodeCount&&a?.episodeCount&&(o.episodeCount=Number(a.episodeCount));let A=o.thumbnail?.trim()?o.thumbnail:void 0,u=!!A;try{await ct.upsert(n,{id:i,name:o.name,thumbnail:A,nativeName:o.nativeName,englishName:o.englishName,popularityScore:o.score??(o.averageScore!=null?o.averageScore/10:void 0),genres:o.genres?JSON.stringify(o.genres.map(c=>typeof c=="string"?c:c?.name).filter(Boolean)):void 0,status:o.status,episodeCount:o.episodeCount!=null?Number(o.episodeCount):void 0,type:o.type,anilistId:o.anilistId})}catch{}if(u&&A){let c=await _t.getById(n,i);if(c&&c.thumbnail!==A)try{await _t.updateThumbnail(n,i,A)}catch{}}if(/^(mal-\d+|-\d+)$/i.test(i)&&o.anilistId&&o.anilistId>0)try{Ia.set(n,i,String(o.anilistId))}catch{}return o||{}}return{}},n=>!!n&&Object.keys(n).length>0)}),video:ee.input(hQe()).query(async({ctx:e,input:t})=>{let r=e.db,n=e.getProviders();try{let i=t.showId,s=jA(i);if(s)try{let h=await cc(s);h?.anilistId&&h.anilistId>0&&(i=String(h.anilistId))}catch{}if(vg(i)){try{let h=await ko.getById(r,i);if(!h||!_d(e,h.provider))return[];let f=String(t.provider||"").toLowerCase(),g=n[h.provider];if(g&&(!f||f===h.provider))return await g.getStreamUrls(h.nativeId,t.episodeNumber,t.mode)||[];let p=await sG(e,h.title,f);if(p)return await p.provider.getStreamUrls(p.nativeId,t.episodeNumber,t.mode)||[]}catch(h){U.error({err:h,showId:i},"Temp show video fetch failed")}return[]}let a=t.provider?.toLowerCase(),A=jA(i)!==null,c=!!!(a&&n[a]?.isDirectId?.(i))&&(/^\d+$/.test(i)||A);if(a&&c){let h=await ct.getById(r,i),f=h?.englishName||h?.name,g=null;if(!f)try{g=await bi(i),f=g?.englishName||g?.name,g&&f&&await ct.upsert(r,{id:i,name:g.name,thumbnail:g.thumbnail,nativeName:g.nativeName,englishName:g.englishName,genres:g.genres?JSON.stringify(g.genres.map(p=>p.name)):void 0,status:g.status,episodeCount:g.episodeCount!=null?Number(g.episodeCount):void 0,type:g.type,anilistId:g.anilistId})}catch(p){U.warn({err:p,provider:a,showId:i},"[Video] AniList metadata lookup failed while resolving numeric showId")}if(f){let p=g?.names?.romaji,m=g?.names?.native,I=g?.names?.synonyms;if(!p||!m)try{let w=await bi(i);p=p||w?.names?.romaji,m=m||w?.names?.native,I=I||w?.names?.synonyms}catch{}let C=[f,p,m,...(I??[]).slice(0,2)].filter(w=>!!w&&w.trim().length>0),B=[...new Set(C.map(w=>w.trim()))].filter((w,R,N)=>N.findIndex(T=>T.toLowerCase()===w.toLowerCase())===R),Q=null;for(let w of B){try{Q=await n[a]?.resolveShowId?.(w,p,t.mode)??null}catch(R){if(R.message==="AUTH_REQUIRED")throw R;Q=null}if(Q)break}if(Q)i=Q;else{U.warn({provider:a,showId:i,title:f,romaji:p},"[Video] resolveShowId failed, attempting fallback provider search");try{let w=await n[a]?.search?.({query:f}),R=ac((w||[]).map(N=>({title:N.name||N.englishName||"",id:N.id||N._id||""})),B);if(R)i=R.item.id;else return U.warn({provider:a,showId:i,title:f},"[Video] fallback provider search returned no results"),[]}catch(w){if(w.message==="AUTH_REQUIRED")throw w;return U.error({err:w,provider:a,showId:i,title:f},"[Video] fallback provider search failed"),[]}}}else return U.warn({provider:a,showId:i},"[Video] numeric showId passed to provider but local meta missing title"),[]}let l=EQe(e,t.provider);return l?await l.getStreamUrls(i,t.episodeNumber,t.mode)||[]:[]}catch(i){if(i.message==="AUTH_REQUIRED")throw Fc(i.provider||t.provider||"animepahe");return U.error({err:i,provider:t.provider},"Provider video fetch failed"),[]}})});var BQe=VBe(mQe,CQe,IQe);var yQe=new So({ttlSeconds:3600,maxKeys:2e3}),QQe=new So({ttlSeconds:3600,maxKeys:2e3});async function bQe(e){let t=e.trim().toLowerCase();if(!t)return null;let r=QQe.get(t);if(r!==void 0)return r;try{let n=new URLSearchParams({title:e.trim(),limit:"5","includes[]":"cover_art","order[relevance]":"desc"});for(let u of["safe","suggestive","erotica","pornographic"])n.append("contentRating[]",u);let i=await fetch(`https://api.mangadex.org/manga?${n.toString()}`,{headers:{"User-Agent":"Dango/3.0",Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!i.ok)return null;let s=await Vt(i),o=[];for(let u of s.data||[]){let c=u.relationships?.find(f=>f.type==="cover_art")?.attributes?.fileName;if(!c)continue;let l=`https://uploads.mangadex.org/covers/${u.id}/${c}.256.jpg`,d=u.attributes?.title,h=d?.en||d?.["ja-ro"]||Object.values(d||{})[0];h&&o.push({title:h,cover:l});for(let f of u.attributes?.altTitles||[]){let g=Object.values(f)[0];g&&o.push({title:g,cover:l})}}let a=ac(o,[e]),A=a?a.item.cover:null;return QQe.set(t,A),A}catch(n){return U.warn({err:n,title:e},"The MangaDex cover lookup failed"),null}}async function wQe(e){let t=String(e).trim().toUpperCase();if(!/^RJ\d{5,}$/.test(t))return null;let r=yQe.get(t);if(r!==void 0)return r;try{let n=await fetch(`https://www.dlsite.com/maniax/product/info/ajax?product_id=${t}`,{headers:{"User-Agent":"Mozilla/5.0",Accept:"application/json"},signal:AbortSignal.timeout(5e3)});if(!n.ok)return null;let s=await Vt(n),a=s[t]??s,A=typeof a?.work_image=="string"?a.work_image:void 0;if(!A)return null;let u=A.startsWith("//")?`https:${A}`:A;return yQe.set(t,u),u}catch(n){return U.warn({err:n,rjCode:t},"The DLsite poster lookup failed"),null}}zd();function oG(e){return e?e.slice(0,8)+"..."+e.slice(-4):"none"}var rQ=U.child({module:"DiscordGatewayRoutes"});function aG(e){let t=String(e||"");if(t.includes("/api/proxy")||t.includes("/api/image-proxy")){let r=t.match(/url=([^&]+)/);if(r)try{t=decodeURIComponent(r[1])}catch(n){return rQ.warn({err:n,thumb:t},"The proxy thumbnail url is not decodable"),""}}return!t.startsWith("https://")||t.includes("localhost")||t.includes("127.0.0.1")?"":t}var AG=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={};for(let o of["sessionId","title","thumbnail","trackLabel","chapterLabel","episodeLabel","rjCode"]){let a=le(t,o);a!==void 0&&(r[o]=a)}let n=t.thumbnails;Array.isArray(n)&&(r.thumbnails=n.map(String).filter(Boolean)),typeof t.isPlaying=="boolean"&&(r.isPlaying=t.isPlaying),typeof t.isAdult=="boolean"&&(r.isAdult=t.isAdult);let i=Ls(t,"currentTime");i!==void 0&&(r.currentTime=i);let s=Ls(t,"duration");return s!==void 0&&(r.duration=s),r}),B0t=()=>pe(e=>{if(e==null)return{};let t=le(ye(e),"page");return t===void 0?{}:{page:t}}),SQe=()=>pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"sessionId");return n!==void 0&&(r.sessionId=n),typeof t.bye=="boolean"&&(r.bye=t.bye),r}),y0t={asmr:{provider:"ASMR",labelField:"trackLabel",fallbackTitle:"ASMR",playingByDefault:!1,state:()=>""},manga:{provider:"Manga",labelField:"chapterLabel",fallbackTitle:"Manga",playingByDefault:!0,state:e=>e?`Reading ${e}`:"Reading"},tv:{provider:"TV",labelField:"episodeLabel",fallbackTitle:"TV",playingByDefault:!1,state:e=>e||"Movie"}};async function Q0t(e,t){let r=e.thumbnail||"";if(t==="asmr"){let n=r;if((!n||n.includes("weeabo0.xyz")||n.includes("japaneseasmr.com"))&&e.rjCode){let s=await wQe(e.rjCode);s&&(n=s)}return(n.includes("/api/image-proxy")||n.includes("weeabo0.xyz"))&&(n=""),{thumb:n,thumbs:e.thumbnails?.filter(Boolean)}}if(t==="manga"){let n=aG(r),i=e.thumbnails?.map(aG).filter(Boolean);if(!n&&e.title){let s=await bQe(e.title);if(s)return{thumb:s,thumbs:[s,...i||[]]}}return{thumb:n,thumbs:i}}return{thumb:aG(r)}}async function uG(e,t,r){if(!e.isServiceEnabled)return;t.sessionId&&e.heartbeat(t.sessionId);let n=y0t[r],i=t[n.labelField]||"",{thumb:s,thumbs:o}=await Q0t(t,r),a=r!=="manga";e.updatePresence({title:(t.title||n.fallbackTitle).slice(0,128),episode:i.slice(0,64),totalEpisodes:"",stateLine:n.state(i).slice(0,64),currentTime:a&&t.currentTime||0,duration:a&&t.duration||0,thumbnail:s,thumbnails:o,isPlaying:t.isPlaying===void 0?n.playingByDefault:t.isPlaying,providerName:n.provider,sessionId:t.sessionId,isAdult:t.isAdult===!0})}var TQe=At({pageStatus:ee.input(B0t()).mutation(async({ctx:e,input:t})=>!t.page||!e.discordRPC.isServiceEnabled?{success:!0}:(e.discordRPC.setIdleStatus(t.page),{success:!0})),heartbeat:ee.input(SQe()).mutation(async({ctx:e,input:t})=>!t.sessionId||!e.discordRPC.isServiceEnabled?{success:!0}:(t.bye?e.discordRPC.removeHeartbeat(t.sessionId):e.discordRPC.heartbeat(t.sessionId),{success:!0})),clear:ee.input(SQe()).mutation(async({ctx:e,input:t})=>e.discordRPC.isServiceEnabled?(e.discordRPC.clearPresence(t.sessionId),{success:!0}):{success:!0}),asmrPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"asmr"),{success:!0})),mangaPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"manga"),{success:!0})),tvPresence:ee.input(AG()).mutation(async({ctx:e,input:t})=>(await uG(e.discordRPC,t,"tv"),{success:!0})),gatewayStatus:ee.query(()=>{let e=Hr.hasToken();return{hasToken:e,masked:e?oG(process.env.DISCORD_GATEWAY_TOKEN):null,enabled:Hr.serviceEnabled}}),gatewaySave:ee.input(pe(e=>{if(e==null)return{};let t=ye(e),r={},n=le(t,"token");return n!==void 0&&(r.token=n),r})).mutation(async({input:e})=>{let t=(e.token||"").trim();if(t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1)),t.length<30)throw it("Token too short");try{return await Rn({DISCORD_GATEWAY_TOKEN:t}),Hr.reloadToken(),rQ.info(`Discord Gateway token saved ${oG(t)} (not logged)`),{ok:!0,masked:oG(t)}}catch(r){throw rQ.error({err:r},"Failed to save Discord Gateway token"),yr("Failed to save token")}}),gatewayRemove:ee.mutation(async()=>{try{return await Rn({DISCORD_GATEWAY_TOKEN:""}),Hr.reloadToken(),rQ.info("Discord Gateway token removed"),{ok:!0}}catch(e){throw rQ.error({err:e},"Failed to remove Discord Gateway token"),yr("Failed to remove token")}})});var DQe=At({settings:cye,queue:hye,watchlist:pye,progress:Cye,notifications:Bye,continueWatching:Qye,discovery:xye,mangaLibrary:vye,mangaProgress:kye,asmrLibrary:Mye,asmrProgress:Fye,tvLibrary:Oye,tvProgress:Pye,tv:Hye,manga:qye,asmr:Wye,tracker:Kye,insights:rQe,auth:nQe,data:BQe,discord:TQe});function NQe(e,t,r){return{...e,lanAuthed:!Sd()||Uy(Jp(t,r))}}var b0t=new wd({isArray:e=>e==="manga",parseTagValue:!1,trimValues:!0});function px(e){return Array.isArray(e)?String(e[0]??""):String(e??"")}function w0t(e){switch(e){case"Plan to Read":return"Planned";case"On Hold":return"On-Hold";case"Reading":case"Completed":case"Dropped":return e;default:return"Planned"}}function S0t(e){try{return DQ(e).remote.address}catch{return e.req.header("x-dango-client-ip")??void 0}}var xQe="x-dango-not-ready";function fm(e,t){return e.header(xQe,"1"),typeof t=="string"?e.text(t,503):e.json(t,503)}async function T0t(e,t){let r=process.hrtime.bigint(),n=new URL(e.req.url),i=`${n.pathname}${n.search}`;await t();let s=Math.round(Number(process.hrtime.bigint()-r)/1e6*10)/10,o=e.res.status,a={method:e.req.method,url:i,status:o,ms:s};o>=500&&!e.res.headers.get(xQe)?U.warn(a,"request failed"):i.startsWith("/api/proxy")||U.trace(`${e.req.method} ${i} ${o} ${s}ms`)}async function D0t(e,t){let r=new Map,n=e.req.header("x-animepahe-ua");n&&r.set("ua",n);let i=e.req.header("x-animepahe-cookie");i&&r.set("cookie",i);let s=e.req.header("x-jasmr-ua");s&&r.set("jasmr_ua",s);let o=e.req.header("x-jasmr-cookie");return o&&r.set("jasmr_cookie",o),aT.run(r,()=>t())}async function N0t(e,t,r){let n;try{n=JSON.parse(r.toString("utf-8"))}catch{return e.json({error:"Invalid backup file."},400)}let i=n?.databases;if(!i||typeof i!="object")return e.json({error:"Invalid backup file: missing databases."},400);let s={anime:t.db,manga:t.mangaDb,tv:t.tvDb,asmr:t.asmrDb},a=Object.keys(ei).map(c=>({key:c,db:s[c],tables:bn[c].tables,libraryTables:bn[c].libraryTables,backupName:bn[c].backupName,setVersion:l=>Hb(c,l)})).filter(c=>i[c.key]!==void 0);if(a.length===0)return e.json({error:"Invalid backup file: no databases found."},400);let A=new Map;try{for(let c of a)A.set(c.key,nl(i[c.key],c.tables,`backup ${c.key}`))}catch(c){return U.warn({err:c},"Multi-database restore rejected: invalid payload"),e.json({error:"Invalid backup file."},400)}let u=[];try{for(let c of a){let l=A.get(c.key);l&&(il(c.db,c.tables,l,{libraryTables:c.libraryTables,backupName:c.backupName}),await c.setVersion(xa(l)),u.push(c.key))}}catch(c){return U.error({err:c,restored:u},"Multi-database restore failed partway"),e.json({error:"Restore failed partway.",restored:u},500)}return U.warn({restored:u},"Databases restored from backup file by user request"),e.json({success:!0,message:"Databases restored.",restored:u})}function R0t(e,t,r,n){let i=ae.IS_DEV?ae.DB_NAME_DEV:ae.DB_NAME_PROD,s=RQe.join(ae.ROOT,"restore_temp.db"),o=RQe.join(ae.ROOT,i);try{hm.writeFileSync(s,r)}catch(A){return U.error({err:A},"Failed to stage legacy database restore file"),Promise.resolve(e.json({error:"Failed to stage restore file."},500))}let a=t.db;return new Promise(A=>{a.close(u=>{if(u){A(e.json({error:"Failed to close database."},500));return}try{a.checkpoint()}catch(c){U.warn({err:c},"WAL checkpoint failed")}try{hm.existsSync(`${o}-wal`)&&hm.unlinkSync(`${o}-wal`),hm.existsSync(`${o}-shm`)&&hm.unlinkSync(`${o}-shm`)}catch(c){U.warn({err:c},"Failed to clean up WAL files")}hm.rename(s,o,async c=>{if(c){try{n.setDb(await n.initializeDatabase(o))}catch(l){U.error({err:l},"Failed to reopen DB after rename failure")}A(e.json({error:"Failed to replace database file."},500));return}try{n.setDb(await n.initializeDatabase(o)),A(e.json({success:!0,message:"Database restored."}))}catch(l){U.error({err:l},"Failed to initialize restored database"),A(e.json({error:"Failed to initialize restored database."},500))}})})})}function vQe(e,t,r,n,i,s,o){let a=new Y6;a.use(T0t),a.use(D0t),a.get("/api/health",u=>{let c=e();return c.shuttingDown?fm(u,{status:"shutting-down",ready:!1}):c.dbReady?u.json({status:"ok",ready:!0}):fm(u,{status:"starting",ready:!1})}),a.use(async(u,c)=>{let l=t();if(l.shuttingDown)return fm(u,"Server is shutting down...");if(!l.dbsReady)return fm(u,"Database initializing...");if(l.bootSyncing&&u.req.method!=="GET"&&u.req.method!=="HEAD"&&u.req.method!=="OPTIONS")return fm(u,"Sync in progress...");await c()});let A=jIe({threshold:1024});return a.use(async(u,c)=>{if(u.req.header("x-no-compression")){await c();return}await A(u,c)}),a.use(async(u,c)=>{let l=u.req.header("origin");if(u.req.method==="OPTIONS"){if(!l||!Ly(l)){await c();return}let d=u.req.header("access-control-request-headers");return new Response(null,{status:204,headers:{"Access-Control-Allow-Origin":l,"Access-Control-Allow-Credentials":"true","Access-Control-Allow-Methods":"GET,HEAD,PUT,PATCH,POST,DELETE",...d?{"Access-Control-Allow-Headers":d}:{},Vary:"Origin"}})}(!l||Ly(l))&&(l&&u.header("Access-Control-Allow-Origin",l),u.header("Access-Control-Allow-Credentials","true"),u.header("Vary","Origin")),await c()}),a.use(async(u,c)=>{let l=u.req.method.toUpperCase();if(!["POST","PUT","DELETE","PATCH"].includes(l)){await c();return}if(u.req.header("sec-fetch-site")==="cross-site"){let f=u.req.header("origin");if(!Ly(f))return u.json({error:"Forbidden: cross-site request rejected"},403)}let h=u.req.header("origin");if(h&&!Ly(h))return u.json({error:"Forbidden: cross-origin request rejected"},403);await c()}),a.get("/api/auth/app-status",u=>{let c=!Sd()||Uy(Jp(u.req.header("authorization"),u.req.header("cookie")));return u.json({hasPassword:Sd(),isAuthenticated:c,port:ae.PORT})}),a.post("/api/auth/app-login",async u=>{let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");if(!Sd())return u.json({success:!0});if(!l)return u.json({error:"Password required"},400);if(!ICe(l))return u.json({error:"Invalid password"},401);let d=BCe();return u.header("Set-Cookie",wCe(d.token,d.expiry)),u.json({success:!0})}),a.post("/api/auth/app-logout",u=>(yCe(Jp(u.req.header("authorization"),u.req.header("cookie"))),u.header("Set-Cookie",SCe()),u.json({success:!0}))),a.post("/api/auth/app-setup",async u=>{if(!f5(u.req.header("x-dango-client-ip")))return u.json({error:"Forbidden"},403);let c=await u.req.json().catch(()=>{}),l=String(c?.password||"");try{return await CCe(l),QCe(),u.json({success:!0,hasPassword:Sd()})}catch{return u.json({error:"Failed to update password"},500)}}),a.use(async(u,c)=>{let l=u.req.path;if(!l.startsWith("/api/")){await c();return}if(bCe.has(l)){await c();return}if(l.startsWith("/api/internal/")&&f5(S0t(u))){await c();return}if(!Sd()){await c();return}if(Uy(Jp(u.req.header("authorization"),u.req.header("cookie")))){await c();return}return u.json({error:"LAN_AUTH_REQUIRED"},401)}),a.all("/api/trpc/*",u=>kBe({endpoint:"/api/trpc",req:u.req.raw,router:DQe,createContext:()=>NQe({...r(),apiCache:o.getApiCache(),getTvProvider:o.getTvProvider,getMangaProvider:o.getMangaProvider,getJasmr:o.getJasmr,getProviders:o.getProviders,getCatalog:i.getCatalog,discordRPC:Qy,offlineDb:pn,malCacheStore:Ur},u.req.header("authorization"),u.req.header("cookie"))})),a.post("/api/import/mal-xml",async u=>{let c=r(),l=await u.req.parseBody().catch(()=>({})),d=l.xmlfile,h=d instanceof File?Buffer.from(await d.arrayBuffer()):void 0,f=qCe(h,{erase:l.erase,useOfflineDb:l.useOfflineDb,skipFallback:l.skipFallback});if(!f.ok)return u.json(f.body,f.status);let g=new TransformStream,p=g.writable.getWriter(),m=new TextEncoder,I=!1;u.req.raw.signal.addEventListener("abort",()=>{I=!0},{once:!0});let C=(B,Q)=>{I||p.write(m.encode(`event: ${B}
986
986
  data: ${JSON.stringify(Q)}
987
987
 
988
988
  `)).catch(()=>{})};return WCe(c.db,f.import,C).finally(()=>{p.close().catch(()=>{})}),new Response(g.readable,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}),a.get("/api/providers",u=>(u.header("Cache-Control","public, max-age=300"),u.json(i.getCatalog()))),a.post("/api/providers/refresh",async u=>{try{return u.json(await i.refresh())}catch(c){return u.json({error:c.message||"refresh failed"},500)}}),a.get("/api/tracker/anilist/callback",u=>u.html(`<!doctype html>
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dango-server",
3
3
  "private": true,
4
- "version": "3.7.2",
4
+ "version": "3.7.3",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.12.0"
@@ -1,10 +0,0 @@
1
- import{u as n,A as C,d as x,h as M,q as N,T as pe,$ as Nt}from"./vendor-core-DfaOB3Rn.js";import{B as ne,M as Bt,S as _e,i as Pt,Y as qt,t as tt,q as de,W as At,g as It}from"./index-BLh_CXtu.js";import{I as Y}from"./vendor-icons-DrybRNxP.js";import{u as Mt}from"./vendor-query-BBT5_sHx.js";const $t="_controls_1ljql_1",Ft="_titleContainer_1ljql_9",Dt="_scheduleInfo_1ljql_15",Rt="_status_1ljql_23",jt="_nextEpisode_1ljql_35",Ot="_watchlistBtn_1ljql_45",Ht="_inList_1ljql_72",Vt="_queueBtn_1ljql_83",Wt="_queueActive_1ljql_95",zt="_modeToggleBtn_1ljql_101",Ut="_modeToggleActive_1ljql_108",Kt="_markWatchedBtn_1ljql_129",Xt="_markWatchedDone_1ljql_143",Gt="_streamPanel_1ljql_154",Qt="_desktopEpisodeActions_1ljql_168",Yt="_sourceLoader_1ljql_174",Jt="_episodeActions_1ljql_187",Zt="_mobileEpisodeActions_1ljql_201",en="_episodeNavBtn_1ljql_205",tn="_primary_1ljql_235",nn="_secondary_1ljql_245",rn="_episodePickerBtn_1ljql_249",on="_queueCountdown_1ljql_253",sn="_speedBoostBadge_1ljql_268",an="_videoContainer_1ljql_299",cn="_loadingOverlay_1ljql_312",ln="_loadingDots_1ljql_326",un="_dot_1ljql_331",dn="_bounce_1ljql_1",fn="_bufferingOverlay_1ljql_348",pn="_bufferingSpinner_1ljql_357",mn="_spin_1ljql_444",hn="_videoIframe_1ljql_366",gn="_videoElementHidden_1ljql_389",yn="_upscalerCanvas_1ljql_394",vn="_upscalerActive_1ljql_407",bn="_upscalerStatusBadge_1ljql_411",_n="_subtitleOverlay_1ljql_426",wn="_spinner_1ljql_444",Sn="_errorOverlay_1ljql_505",Cn="_retryButton_1ljql_515",kn="_detailsToggleBtn_1ljql_528",En="_descriptionSection_1ljql_551",Ln="_synopsisFlat_1ljql_559",xn="_fullscreenActive_1ljql_593",Tn="_errorSubtext_1ljql_637",bo={controls:$t,titleContainer:Ft,scheduleInfo:Dt,status:Rt,nextEpisode:jt,watchlistBtn:Ot,inList:Ht,queueBtn:Vt,queueActive:Wt,modeToggleBtn:zt,modeToggleActive:Ut,markWatchedBtn:Kt,markWatchedDone:Xt,streamPanel:Gt,desktopEpisodeActions:Qt,sourceLoader:Yt,episodeActions:Jt,mobileEpisodeActions:Zt,episodeNavBtn:en,primary:tn,secondary:nn,episodePickerBtn:rn,queueCountdown:on,speedBoostBadge:sn,videoContainer:an,loadingOverlay:cn,loadingDots:ln,dot:un,bounce:dn,bufferingOverlay:fn,bufferingSpinner:pn,spin:mn,videoIframe:hn,videoElementHidden:gn,upscalerCanvas:yn,upscalerActive:vn,upscalerStatusBadge:bn,subtitleOverlay:_n,spinner:wn,errorOverlay:Sn,retryButton:Cn,detailsToggleBtn:kn,descriptionSection:En,synopsisFlat:Ln,fullscreenActive:xn,errorSubtext:Tn},Nn="_playerPageLayout_q7ra9_1",Bn="_noSidebar_q7ra9_15",Pn="_episodeSidebar_q7ra9_19",qn="_playerMain_q7ra9_32",An="_videoPlayerWrapper_q7ra9_40",In="_playerInfoHeader_q7ra9_56",Mn="_playerAnimeCard_q7ra9_62",$n="_playerInfoContainer_q7ra9_74",Fn="_infoColumns_q7ra9_86",Dn="_videoTitleSection_q7ra9_107",Rn="_theaterMode_q7ra9_150",_o={playerPageLayout:Nn,noSidebar:Bn,episodeSidebar:Pn,playerMain:qn,videoPlayerWrapper:An,playerInfoHeader:In,playerAnimeCard:Mn,playerInfoContainer:$n,infoColumns:Fn,videoTitleSection:Dn,theaterMode:Rn},jn="_shell_41rxp_1",On="_stage_41rxp_37",Hn="_shellFill_41rxp_85",Vn="_shellFullscreen_41rxp_93",Wn="_uiLayer_41rxp_107",zn="_volumeWrap_41rxp_118",Un="_volumeSlider_41rxp_124",ae={shell:jn,stage:On,shellFill:Hn,shellFullscreen:Vn,uiLayer:Wn,volumeWrap:zn,volumeSlider:Un},Kn={fontSize:"subtitleFontSize",position:"subtitlePosition",bgOpacity:"subtitleBgOpacity",bgColor:"subtitleBgColor",textColor:"subtitleTextColor",edge:"subtitleEdge",bold:"subtitleBold"},Z={fontSize:1.8,position:0,bgOpacity:.5,bgColor:"#000000",textColor:"#ffffff",edge:"shadow",bold:!1},Ne=(e,r,t)=>Math.max(r,Math.min(t,e)),Be=e=>typeof e=="string"&&/^#[0-9a-fA-F]{6}$/.test(e),ke=(e,r,t,s)=>{try{const o=localStorage.getItem(e);if(o===null)return r;const i=parseFloat(o);return Number.isFinite(i)?Ne(i,t,s):r}catch{return r}};function Xn(){let e=Z.edge,r=Z.bgColor,t=Z.textColor,s=Z.bold;try{const o=localStorage.getItem("subtitleEdge");(o==="shadow"||o==="outline"||o==="none")&&(e=o);const i=localStorage.getItem("subtitleBgColor");Be(i)&&(r=i);const f=localStorage.getItem("subtitleTextColor");Be(f)&&(t=f);const v=localStorage.getItem("subtitleBold");v!==null&&(s=v==="true")}catch{}return{fontSize:ke("subtitleFontSize",Z.fontSize,.5,10),position:ke("subtitlePosition",Z.position,0,100),bgOpacity:ke("subtitleBgOpacity",Z.bgOpacity,0,1),bgColor:r,textColor:t,edge:e,bold:s}}function st(e,r){const t=`rgba(0, 0, 0, ${Ne(r,0,1)})`;if(!Be(e))return t;const s=parseInt(e.slice(1,3),16),o=parseInt(e.slice(3,5),16),i=parseInt(e.slice(5,7),16);return`rgba(${s}, ${o}, ${i}, ${Ne(r,0,1)})`}function at(e,r){return e==="none"?r<=0?"0 1px 3px rgba(0, 0, 0, 0.9)":"none":e==="outline"?["-1px 0 0 black","1px 0 0 black","0 -1px 0 black","0 1px 0 black","-1px -1px 0 black","1px -1px 0 black","-1px 1px 0 black","1px 1px 0 black","0 0 6px rgba(0, 0, 0, 0.9)"].join(", "):"0 0 4px black, 0 1px 2px rgba(0, 0, 0, 0.8)"}function wo(e){return`
2
- video::cue {
3
- font-size: ${e.fontSize}rem !important;
4
- color: ${e.textColor} !important;
5
- background-color: ${st(e.bgColor,e.bgOpacity)} !important;
6
- font-weight: ${e.bold?"bold":"normal"} !important;
7
- text-shadow: ${at(e.edge,e.bgOpacity)} !important;
8
- }
9
- `}function So(e){return[`font-size: ${e.fontSize}rem`,`color: ${e.textColor}`,`background-color: ${st(e.bgColor,e.bgOpacity)}`,`font-weight: ${e.bold?"700":"400"}`,`text-shadow: ${at(e.edge,e.bgOpacity)}`,"padding: 0.2em 0.5em","border-radius: 0.25em","text-align: center","position: absolute","left: 50%","transform: translateX(-50%)","max-width: 92%","white-space: pre-wrap","overflow-wrap: break-word","line-height: 1.4"].join(`;
10
- `)+";"}const Gn=new Set(["b","i","u","strong","em"]);function Co(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/&lt;(\/?)([a-zA-Z]+)&gt;/g,(t,s,o)=>Gn.has(o.toLowerCase())?`<${s}${o.toLowerCase()}>`:t)}function ko(e){return e.replace(/<[^>]*>/g,"")}const Eo=["#ffffff","#ffff00","#7CFC00","#00e5ff","#ff9ff3","#ffa502"],Lo=["#000000","#1e272e","#2f3542","#3d0c02","#0c3d2e","#ffffff"];function xo(e,r){const t=Number.isFinite(e)?e*16:Z.fontSize*16;return!Number.isFinite(r)||r<=0?t/16:Math.min(t,Math.max(13,r*.07))/16}function To(e){const r=Math.abs(e/1e3).toFixed(1);return e>0?`+${r}s`:e<0?`-${r}s`:"0.0s"}function No(e,r){const t=e.clientWidth||0,s=e.clientHeight||0,o=e.videoWidth>0&&e.videoHeight>0?e.videoWidth/e.videoHeight:0;let i=s;o>0&&t>0&&s>0&&(i=t/s>o?s:t/o);const f=Math.max(0,(s-i)/2),v=Math.max(0,Math.min(100,Number(r)||0))/100*i;return f+v}const Bo=({isOpen:e,onClose:r,title:t,message:s,resumeLabel:o="Resume",restartLabel:i="Start Over",onResume:f,onRestart:v})=>n(Bt,{isOpen:e,onClose:r,title:t,width:"sm",children:n("div",{style:{padding:"1rem",textAlign:"center"},children:[n("p",{children:s}),n("div",{style:{marginTop:"1rem",display:"flex",gap:"10px",justifyContent:"center"},children:[n(ne,{variant:"secondary",onClick:v,children:i}),n(ne,{onClick:f,children:o})]})]})}),Qn="_centerControls_bxt8c_1",Yn="_centerSkipBtn_bxt8c_15",Jn="_centerPlayPause_bxt8c_37",Zn="_playIconOffset_bxt8c_65",fe={centerControls:Qn,centerSkipBtn:Yn,centerPlayPause:Jn,playIconOffset:Zn},Po=({isPlaying:e,onTogglePlay:r,onSkipBack:t,onSkipForward:s,skipSeconds:o=10})=>n("div",{className:fe.centerControls,onClick:i=>i.stopPropagation(),children:[n("button",{className:fe.centerSkipBtn,onClick:t,title:`Skip back ${o}s`,"aria-label":`Skip back ${o} seconds`,children:n(Y,{name:"replay-10"})}),n("button",{className:fe.centerPlayPause,"data-speed-boost-ignore":"true",onClick:r,"aria-label":e?"Pause":"Play",children:e?n(Y,{name:"pause"}):n(Y,{name:"play",className:fe.playIconOffset})}),n("button",{className:fe.centerSkipBtn,onClick:s,title:`Skip forward ${o}s`,"aria-label":`Skip forward ${o} seconds`,children:n(Y,{name:"forward-10"})})]}),qo=({visible:e,title:r,episode:t,onBack:s,classes:o})=>n("div",{className:`${o.overlay} ${e?"":o.hidden} `,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none"},children:n("div",{className:o.top,onClick:i=>i.stopPropagation(),children:[n("button",{className:o.backBtn,onClick:i=>{i.stopPropagation(),s()},title:"Back","aria-label":"Back",children:n(Y,{name:"chevron-left"})}),n("div",{className:o.titleInfo,children:[n("span",{className:o.title,children:r}),t&&n("span",{className:o.episode,children:t})]})]})}),Ao=({classes:e,videoRef:r,duration:t,formatTime:s,isScrubbing:o,buffered:i="auto",onSeek:f,onScrubStart:v,onScrubMove:c,onScrubEnd:g,timeLabelRef:b,children:u})=>{const E=C(null),S=C(null),l=C(null),d=C(null),_=C(null),y=C(!1),k=C(o);k.current=o;const m=C({onScrubMove:c,onScrubEnd:g});m.current={onScrubMove:c,onScrubEnd:g};const[B,P]=x({time:0,position:null});M(()=>{const h=r.current;if(!h)return;const w=W=>{const X=W/t*100||0;S.current&&(S.current.style.width=`${X}%`),l.current&&(l.current.style.left=`${X}%`),b?.current&&(b.current.innerText=`${s(W)} / ${s(t)}`)},D=()=>{o||w(h.currentTime)},$=()=>{if(i==="auto"&&h.buffered.length>0){const X=h.buffered.end(h.buffered.length-1)/t*100||0;d.current&&(d.current.style.width=`${X}%`)}};return w(h.currentTime),$(),h.addEventListener("timeupdate",D),h.addEventListener("progress",$),()=>{h.removeEventListener("timeupdate",D),h.removeEventListener("progress",$)}},[r,t,o,i,s,b]);const H=h=>{if(!E.current)return 0;const w=E.current.getBoundingClientRect();return Math.min(1,Math.max(0,(h-w.left)/w.width))},K=h=>{const w=h*t,D=w/t*100||0;S.current&&(S.current.style.width=`${D}%`),l.current&&(l.current.style.left=`${D}%`),b?.current&&(b.current.innerText=`${s(w)} / ${s(t)}`);const $=E.current?.getBoundingClientRect();P({time:w,position:$?h*$.width:null})};M(()=>{if(!o){_.current=null;return}const h=D=>{if(_.current!==null&&D.pointerId!==_.current||!t)return;const $=H(D.clientX);m.current.onScrubMove($);const W=$*t,X=W/t*100||0;S.current&&(S.current.style.width=`${X}%`),l.current&&(l.current.style.left=`${X}%`),b?.current&&(b.current.innerText=`${s(W)} / ${s(t)}`);const re=E.current?.getBoundingClientRect();P({time:W,position:re?$*re.width:null})},w=D=>{_.current!==null&&D.pointerId!==_.current||(_.current=null,y.current=!0,D.pointerType!=="mouse"&&P({time:0,position:null}),m.current.onScrubEnd())};return document.addEventListener("pointermove",h),document.addEventListener("pointerup",w),document.addEventListener("pointercancel",w),()=>{document.removeEventListener("pointermove",h),document.removeEventListener("pointerup",w),document.removeEventListener("pointercancel",w)}},[o,t,s,b]);const V=h=>{if(h.pointerType==="mouse"&&h.button!==0||!r.current||!t)return;h.preventDefault(),_.current=h.pointerId;try{E.current?.setPointerCapture(h.pointerId)}catch{}k.current||v();const w=H(h.clientX);c(w),K(w)},T=h=>{if(!t||k.current||h.pointerType!=="mouse")return;const w=H(h.clientX);P({time:w*t,position:h.clientX-(E.current?.getBoundingClientRect().left??0)})},z=h=>{if(!(_.current!==null&&h.pointerId!==_.current)&&k.current){_.current=null,y.current=!0,h.pointerType!=="mouse"&&P({time:0,position:null});try{E.current?.hasPointerCapture(h.pointerId)&&E.current.releasePointerCapture(h.pointerId)}catch{}g()}};return n("div",{className:`${e.container} ${o&&e.scrubbing?e.scrubbing:""}`,ref:E,role:"slider","aria-label":"Seek","aria-valuemin":0,"aria-valuemax":Math.round(t||0),"aria-valuenow":Math.round((Number(S.current?.style.width?.replace("%",""))||0)*(t||0)/100),tabIndex:0,onClick:h=>{if(y.current){y.current=!1;return}!r.current||isNaN(t)||t===0||f(H(h.clientX))},onPointerDown:V,onPointerMove:T,onPointerUp:z,onPointerCancel:z,onMouseMove:h=>{if(o||!t)return;const w=H(h.clientX);P({time:w*t,position:h.clientX-(E.current?.getBoundingClientRect().left??0)})},onMouseLeave:()=>{o||P({time:0,position:null})},onKeyDown:h=>{if(!(!r.current||!t)&&(h.key==="ArrowRight"||h.key==="ArrowLeft")){h.preventDefault();const w=(h.key==="ArrowRight"?5:-5)/t,D=r.current.currentTime/t||0;f(Math.min(1,Math.max(0,D+w)))}},children:[B.position!==null&&n("div",{className:e.timeBubble,style:{left:B.position},children:s(B.time)}),n("div",{className:e.bar,children:[n("div",{className:e.buffered,ref:d,style:i==="full"?{width:"100%"}:void 0}),n("div",{className:e.watched,ref:S}),n("div",{className:e.thumb,ref:l,onMouseDown:h=>{h.preventDefault(),r.current&&(k.current||v())}}),u]})]})};function Ee(){try{if(typeof window>"u")return!1;const e=window.matchMedia?.("(pointer: coarse)").matches??!1,t=(navigator.maxTouchPoints??0)>0||"ontouchstart"in window;return e||t}catch{return!1}}function ct(){const[e,r]=x(Ee);return M(()=>{r(Ee());let t=null;const s=()=>r(Ee());try{t=window.matchMedia("(pointer: coarse)"),t.addEventListener?t.addEventListener("change",s):t.addListener(s)}catch{}return window.addEventListener("touchstart",s,{passive:!0,once:!0}),()=>{try{t&&(t.removeEventListener?t.removeEventListener("change",s):t.removeListener(s))}catch{}window.removeEventListener("touchstart",s)}},[]),e}const er=450,Io=({muted:e,volume:r,volumeIcon:t,buttonClassName:s,sliderClassName:o,onToggleMute:i,onVolumeChange:f,onExpandedChange:v})=>{const c=ct(),[g,b]=x(!1),u=C(null),E=C(!1),S=C(null),l=N(m=>{b(m),v?.(m)},[v]);M(()=>()=>{u.current&&window.clearTimeout(u.current)},[]),M(()=>{if(!g)return;const m=B=>{S.current&&!S.current.contains(B.target)&&l(!1)};return document.addEventListener("pointerdown",m),()=>document.removeEventListener("pointerdown",m)},[g,l]);const d=e?0:r,_=()=>{E.current=!1,u.current&&window.clearTimeout(u.current),u.current=window.setTimeout(()=>{E.current=!0,l(!0)},er)},y=()=>{u.current&&(window.clearTimeout(u.current),u.current=null)},k=m=>{if(m.stopPropagation(),E.current){E.current=!1;return}if(c){g?i():l(!0);return}i()};return n("div",{ref:S,className:ae.volumeWrap,"data-expanded":g?"true":"false",onContextMenu:m=>m.preventDefault(),children:[n("button",{type:"button",className:s,onClick:k,onPointerDown:_,onPointerUp:y,onPointerLeave:y,onContextMenu:m=>m.preventDefault(),"aria-label":e?"Unmute":"Mute","aria-expanded":g,children:t}),n("input",{type:"range",min:"0",max:"1",step:"0.05",value:d,onChange:m=>f(parseFloat(m.currentTarget.value)),onClick:m=>m.stopPropagation(),onPointerDown:m=>m.stopPropagation(),onContextMenu:m=>m.preventDefault(),className:`${ae.volumeSlider} ${o??""}`,style:{"--volume-percent":`${d*100}%`},"aria-label":"Volume"})]})},nt=280;function tr(e){return e?!!e.closest('button, input, select, textarea, a, [role="button"], [data-player-ui="true"]'):!1}const Mo=({player:e,topBar:r,centerControls:t,bottomBar:s,settingsPanel:o,overlays:i,isInteracting:f=!1,className:v,chromeDisabled:c=!1,onStageClick:g,children:b})=>{const{state:u,refs:E,actions:S}=e,l=E.playerContainerRef,_=ct()?5e3:3e3,y=C(0),k=C(null),m=C(f);m.current=f;const B=N(()=>{const T=S.inactivityTimer.current;T&&(window.clearTimeout(T),S.inactivityTimer.current=null)},[S]),P=N(()=>{B(),u.isPlaying&&(m.current||u.useNativeControls||(S.inactivityTimer.current=window.setTimeout(()=>{if(m.current)return;S.setShowControls(!1);const T=l.current;T&&u.isFullscreen&&(T.style.cursor="none")},_)))},[S,B,l,_,u.isFullscreen,u.isPlaying,u.useNativeControls]),H=N(()=>{const T=l.current;T&&(T.style.cursor="default"),!u.showControls&&!u.useNativeControls&&S.setShowControls(!0),P()},[S,l,P,u.showControls,u.useNativeControls]);M(()=>{if(u.showControls){if(!u.isPlaying){B();return}if(f||u.isScrubbing||u.showSettings||u.showVolumeSlider){S.setShowControls(!0),B();return}P()}},[S,B,f,P,u.isPlaying,u.isScrubbing,u.showControls,u.showSettings,u.showVolumeSlider]),M(()=>()=>B(),[B]);const K=N(T=>{const z=T.target;if(tr(z))return;g?.();const h=Date.now(),w=h-y.current<nt;if(y.current=h,w){k.current&&(window.clearTimeout(k.current),k.current=null),S.toggleFullscreen();return}k.current&&window.clearTimeout(k.current),k.current=window.setTimeout(()=>{k.current=null,S.setShowControls(!u.showControls),u.showControls?P():H()},nt)},[S,g,P,u.showControls,H]);M(()=>()=>{k.current&&window.clearTimeout(k.current)},[]);const V=u.showControls||u.isScrubbing||u.showSettings||u.showVolumeSlider;return n("div",{ref:l,className:`${ae.shell} ${u.isFullscreen?ae.shellFullscreen:""} ${v??""}`,onContextMenu:T=>T.preventDefault(),onPointerMove:T=>{T.pointerType==="mouse"&&H()},onMouseLeave:()=>{window.matchMedia?.("(hover: hover) and (pointer: fine)").matches&&u.isPlaying&&!m.current&&S.setShowControls(!1)},children:[n("div",{className:ae.stage,onClick:K,onContextMenu:T=>T.preventDefault(),children:b}),i,!c&&!u.useNativeControls&&n("div",{className:ae.uiLayer,onContextMenu:T=>T.preventDefault(),children:[n("div",{"data-player-ui":"true",children:r}),V&&t&&n("div",{"data-player-ui":"true",children:t}),n("div",{"data-player-ui":"true",children:s}),o&&n("div",{"data-player-ui":"true",children:o})]})]})},nr=e=>(e.language??e.lang??"").toLowerCase(),rr=e=>(e.label??"").toLowerCase(),or=e=>`${e.language??e.lang??""}|||${e.label??""}`,sr=e=>nr(e).startsWith("en")||rr(e).includes("english");function $o(e,r){if(e.length===0||r?.enabled===!1)return-1;const t=r?.lastKey??null;if(t){const o=e.findIndex(i=>or(i)===t);if(o>=0)return o}const s=e.findIndex(sr);return s>=0?s:0}const ar="_statusArea_1xccu_1",cr="_toggleBtn_1xccu_20",ir="_shortcuts_1xccu_46",lr="_shortcutGroup_1xccu_56",ur="_shortcut_1xccu_46",dr="_key_1xccu_70",fr="_label_1xccu_91",A={statusArea:ar,toggleBtn:cr,shortcuts:ir,shortcutGroup:lr,shortcut:ur,key:dr,label:fr},Fo=({showTheater:e=!0})=>{const[r,t]=x(!1);return n("div",{className:A.statusArea,children:[n("button",{type:"button",className:A.toggleBtn,onClick:()=>t(s=>!s),"aria-expanded":r,"aria-controls":"player-shortcuts",children:[n(Y,{name:"keyboard",size:14}),n("span",{children:"Keyboard Shortcuts"}),r?n(Y,{name:"chevron-up",size:12}):n(Y,{name:"chevron-down",size:12})]}),r&&n("div",{id:"player-shortcuts",className:A.shortcuts,children:[n("div",{className:A.shortcutGroup,children:[n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"↑"}),n("span",{className:A.key,children:"↓"}),n("span",{className:A.label,children:"Volume"})]}),n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"←"}),n("span",{className:A.key,children:"→"}),n("span",{className:A.label,children:"Seek"})]})]}),n("div",{className:A.shortcutGroup,children:[n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"Space"}),n("span",{className:A.label,children:"Play/Pause"})]}),n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"F"}),n("span",{className:A.label,children:"Fullscreen"})]}),n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"M"}),n("span",{className:A.label,children:"Mute"})]}),e&&n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"T"}),n("span",{className:A.label,children:"Theater"})]}),n("div",{className:A.shortcut,children:[n("span",{className:A.key,children:"N"}),n("span",{className:A.label,children:"Next"})]})]})]})]})},pr="_episodeListContainer_9tyin_1",mr="_drawerContainer_9tyin_9",hr="_episodeListHeader_9tyin_14",gr="_drawerHeader_9tyin_20",yr="_episodeListTitle_9tyin_29",vr="_rangeSelector_9tyin_41",br="_rangeButton_9tyin_47",_r="_active_9tyin_70",wr="_episodeList_9tyin_1",Sr="_drawerList_9tyin_89",Cr="_episodeItem_9tyin_118",kr="_watched_9tyin_145",Er="_episodeThumb_9tyin_167",Lr="_episodeText_9tyin_176",xr="_episodeLabel_9tyin_184",Tr="_episodeSub_9tyin_189",I={episodeListContainer:pr,drawerContainer:mr,episodeListHeader:hr,drawerHeader:gr,episodeListTitle:yr,rangeSelector:vr,rangeButton:br,active:_r,episodeList:wr,drawerList:Sr,episodeItem:Cr,watched:kr,episodeThumb:Er,episodeText:Lr,episodeLabel:xr,episodeSub:Tr},Nr=({episodes:e,currentEpisode:r,watchedEpisodes:t=[],onEpisodeClick:s,variant:o="sidebar",title:i="Episodes",header:f})=>{const[v,c]=x(0),g=C(null),b=pe(()=>e.map(l=>typeof l=="string"?{id:l,label:`Episode ${l}`}:l),[e]),u=pe(()=>new Set(t),[t]);M(()=>{const l=g.current;if(!l)return;let d=l.parentElement;for(;d;){const k=window.getComputedStyle(d);if((k.overflowY==="auto"||k.overflowY==="scroll")&&d.scrollHeight>d.clientHeight)break;d=d.parentElement}if(!d)return;const _=d.getBoundingClientRect(),y=l.getBoundingClientRect();d.scrollTop+=y.top+y.height/2-(_.top+d.clientHeight/2)},[r,v]);const E=pe(()=>{if(b.length<=100)return[];const l=[];for(let d=0;d<b.length;d+=100){const _=d+1,y=Math.min(d+100,b.length);l.push(`${_}-${y}`)}return l},[b]),S=pe(()=>{if(E.length===0)return b;const l=E[v];if(!l)return b;const[d,_]=l.split("-"),y=parseInt(d,10),k=parseInt(_,10);return b.slice(y-1,k)},[b,E,v]);return n("div",{className:`${I.episodeListContainer} ${o==="drawer"?I.drawerContainer:""}`,children:[n("div",{className:`${I.episodeListHeader} ${o==="drawer"?I.drawerHeader:""}`,children:[f,n("h3",{className:I.episodeListTitle,children:i}),E.length>0&&n("div",{className:I.rangeSelector,children:E.map((l,d)=>n("button",{className:`${I.rangeButton} ${v===d?I.active:""}`,onClick:()=>c(d),children:l},l))})]}),n("div",{className:`${I.episodeList} ${o==="drawer"?I.drawerList:""}`,children:S.map(l=>{const d=l.id===r,_=u.has(l.id)||l.watched===!0;return n("div",{ref:d?g:void 0,className:`${I.episodeItem} ${_?I.watched:""} ${d?I.active:""}`,onClick:()=>s(l.id),children:[l.thumbnail&&n("img",{src:l.thumbnail,alt:"",loading:"lazy",decoding:"async",className:I.episodeThumb}),n("span",{className:I.episodeText,children:[n("span",{className:I.episodeLabel,children:l.label??`Episode ${l.id}`}),l.sublabel&&n("span",{className:I.episodeSub,children:l.sublabel})]})]},l.id)})})]})},Do=({variant:e="sidebar",count:r=12})=>n("div",{className:`${I.episodeListContainer} ${e==="drawer"?I.drawerContainer:""}`,children:[n("div",{className:`${I.episodeListHeader} ${e==="drawer"?I.drawerHeader:""}`,children:[n("h3",{className:I.episodeListTitle,children:"Episodes"}),n("div",{className:I.rangeSelector,children:[n(_e,{width:"60px",height:"28px",variant:"rectangular"}),n(_e,{width:"60px",height:"28px",variant:"rectangular"}),n(_e,{width:"60px",height:"28px",variant:"rectangular"})]})]}),n("div",{className:`${I.episodeList} ${e==="drawer"?I.drawerList:""}`,children:Array.from({length:r}).map((t,s)=>n("div",{className:I.episodeItem,style:{border:"none",background:"transparent"},children:n(_e,{width:"120px",height:"1.2rem",variant:"text"})},s))})]}),Br="_shell_cys6s_1",Pr="_overlay_cys6s_10",qr="_drawer_cys6s_21",Ar="_handle_cys6s_56",Ir="_header_cys6s_64",Mr="_headerCopy_cys6s_73",$r="_kicker_cys6s_79",Fr="_title_cys6s_87",Dr="_closeBtn_cys6s_94",Rr="_body_cys6s_116",Q={shell:Br,overlay:Pr,drawer:qr,handle:Ar,header:Ir,headerCopy:Mr,kicker:$r,title:Fr,closeBtn:Dr,body:Rr};function Ro({isOpen:e,onClose:r,episodes:t,currentEpisode:s,watchedEpisodes:o=[],onEpisodeClick:i,title:f,header:v}){return M(()=>{if(!e)return;const c=b=>{b.key==="Escape"&&r()},g=document.body.style.overflow;return document.body.style.overflow="hidden",document.addEventListener("keydown",c),()=>{document.body.style.overflow=g,document.removeEventListener("keydown",c)}},[e,r]),e?Nt(n("div",{className:Q.shell,role:"dialog","aria-modal":"true","aria-label":"Episode picker",children:[n("button",{className:Q.overlay,type:"button",onClick:r,"aria-label":"Close episodes"}),n("aside",{className:Q.drawer,children:[n("div",{className:Q.handle}),n("div",{className:Q.header,children:[n("div",{className:Q.headerCopy,children:[n("span",{className:Q.kicker,children:"Episode picker"}),n("h3",{className:Q.title,children:"Choose an episode"})]}),n("button",{className:Q.closeBtn,type:"button",onClick:r,"aria-label":"Close",children:n(Y,{name:"times"})})]}),n("div",{className:Q.body,children:n(Nr,{episodes:t,currentEpisode:s,watchedEpisodes:o,onEpisodeClick:i,variant:"drawer",title:f,header:v})})]})]}),document.body):null}const jr="_sourceSelectionContainer_1am19_1",Or="_providerSelectContainer_1am19_14",Hr="_providerSelect_1am19_14",Vr="_sourceSelect_1am19_1",Wr="_sourceButtons_1am19_70",zr="_sourceButton_1am19_70",Ur="_active_1am19_95",jo={sourceSelectionContainer:jr,providerSelectContainer:Or,providerSelect:Hr,sourceSelect:Vr,sourceButtons:Wr,sourceButton:zr,active:Ur};function qe(){return document}function it(e){const r=qe();if(document.fullscreenElement)return document.fullscreenElement;if(r.webkitFullscreenElement)return r.webkitFullscreenElement;const t=e;return t?.webkitDisplayingFullscreen?t:null}function ce(e){return it(e)!==null}async function Kr(e,r){if(it(r))return;const t=e;try{if(typeof e.requestFullscreen=="function"){await e.requestFullscreen();return}if(typeof t.webkitRequestFullscreen=="function"){await t.webkitRequestFullscreen();return}if(typeof t.webkitRequestFullScreen=="function"){await t.webkitRequestFullScreen();return}}catch{}const s=r;if(s&&typeof s.webkitEnterFullscreen=="function"){if(s.webkitSupportsFullscreen===!1)return;try{await s.webkitEnterFullscreen()}catch{}}}async function Xr(e){const r=qe();try{if(document.fullscreenElement&&typeof document.exitFullscreen=="function"){await document.exitFullscreen();return}if(r.webkitFullscreenElement&&typeof r.webkitExitFullscreen=="function"){await r.webkitExitFullscreen();return}}catch{}const t=e;if(t?.webkitDisplayingFullscreen&&typeof t.webkitExitFullscreen=="function"){try{t.webkitExitFullscreen()}catch{}return}try{typeof r.webkitCancelFullScreen=="function"?r.webkitCancelFullScreen():!document.fullscreenElement&&typeof document.exitFullscreen=="function"&&(document.fullscreenElement??r.webkitFullscreenElement)&&await document.exitFullscreen()}catch{}}async function Gr(e,r){!e&&!r||(ce(r)?await Xr(r):e&&await Kr(e,r))}function Qr(e,r){const t=()=>{try{r(ce(e()))}catch{}},s=qe(),o=t;s.addEventListener("fullscreenchange",t),s.addEventListener("webkitfullscreenchange",o),s.addEventListener("webkitbeginfullscreen",o,!0),s.addEventListener("webkitendfullscreen",o,!0);const i=e();return i?.addEventListener("webkitbeginfullscreen",o),i?.addEventListener("webkitendfullscreen",o),()=>{s.removeEventListener("fullscreenchange",t),s.removeEventListener("webkitfullscreenchange",o),s.removeEventListener("webkitbeginfullscreen",o,!0),s.removeEventListener("webkitendfullscreen",o,!0),i?.removeEventListener("webkitbeginfullscreen",o),i?.removeEventListener("webkitendfullscreen",o)}}const Oo=({skipIntervals:e,showId:r,episodeNumber:t,episodeCount:s,sourceType:o,showMeta:i})=>{const f=Mt(),v=Pt(),c=C(null),g=C(null),b=C(null),u=C(!1),E=C(null),S=C(0),l=C({mouse:!1,keyboard:!1}),d=C(null),_=C(null),y=C(!1),k=C(Math.random().toString(36).substring(2)),[m,B]=x(!1),[P,H]=x(()=>{try{return localStorage.getItem("playerMuted")==="true"}catch{return!1}}),[K,V]=x(()=>{try{const a=parseFloat(localStorage.getItem("playerVolume")||"");return isNaN(a)?1:Math.max(0,Math.min(1,a))}catch{return 1}}),[T,z]=x(!1),[h,w]=x(0),[D,$]=x(!0),[W,X]=x(!1),[re,lt]=x(localStorage.getItem("autoSkipEnabled")==="true"),[ut,Se]=x(null),[ee]=x(Xn),[dt,Ae]=x(ee.fontSize),[ft,Ie]=x(ee.position),[pt,Me]=x(ee.bgOpacity),[mt,$e]=x(ee.bgColor),[ht,Fe]=x(ee.textColor),[gt,De]=x(ee.edge),[yt,Re]=x(ee.bold),je=N((a,L)=>{if({fontSize:p=>typeof p!="number"?!1:(Ae(p),!0),position:p=>typeof p!="number"?!1:(Ie(p),!0),bgOpacity:p=>typeof p!="number"?!1:(Me(p),!0),bgColor:p=>typeof p!="string"?!1:($e(p),!0),textColor:p=>typeof p!="string"?!1:(Fe(p),!0),edge:p=>p!=="shadow"&&p!=="outline"&&p!=="none"?!1:(De(p),!0),bold:p=>typeof p!="boolean"?!1:(Re(p),!0)}[a](L))try{localStorage.setItem(Kn[a],String(L))}catch{}},[]),[vt,bt]=x([]),[_t,wt]=x(null),[St,Ct]=x(!1),[kt,Et]=x(!1),[me,G]=x(!1),[Lt,he]=x(!1),[xt,Oe]=x(()=>{try{return localStorage.getItem("playerUseNativeControls")==="true"}catch{return!1}}),ie=C(!1),Ce=C(-1),ge=N(()=>{const a=c.current;return!r||!t||!i?.name?null:{showId:r,episodeNumber:t,episodeCount:s,currentTime:a?a.currentTime:0,duration:a?a.duration:0,showName:i.name,showThumbnail:i.thumbnail,nativeName:i.names?.native,englishName:i.names?.english,genres:Array.isArray(i.genres)?i.genres.map(L=>typeof L=="string"?L:L?.name).filter(Boolean):void 0,popularityScore:i.score,type:i.type,isPlaying:a?!a.paused:!0,sessionId:k.current,isAdult:i.isAdult}},[r,t,s,i]),R=N((a=!1,L=!1)=>{if(ie.current)return!1;const q=ge();if(!q)return!1;const p=c.current;if(!p&&o!=="iframe")return!1;const F=p?p.currentTime>=p.duration*.8:!1;let j=p?p.currentTime:0;if(a&&F&&(j=p?p.duration:0),!L){if(j===0&&!F)return!1;const U=p?Math.abs(j-Ce.current):0;if(!a&&p&&j!==p.duration&&U<5)return!1}return q.currentTime=j,Ce.current=j,a?(async()=>{try{await tt.progress.updateProgress.mutate(q),f.invalidateQueries({queryKey:[de.videoSources,r,t]}),f.invalidateQueries({queryKey:[de.continueWatching]}),f.invalidateQueries({queryKey:[de.thisWeekSchedule]}),f.invalidateQueries(v.continueWatching.pathFilter())}catch(U){console.error("Failed to update progress:",U)}})():qt("progress.updateProgress",q).catch(U=>console.error("Failed to update progress:",U)),!0},[ge,o,f,r,t,v.continueWatching]);M(()=>{const a=c.current;a&&(a.volume=K,a.muted=P)},[c,K,P]),M(()=>{const a=()=>{ie.current||R(!0)};window.addEventListener("beforeunload",a);const L=E,q=b;return()=>{window.removeEventListener("beforeunload",a),ie.current||R(!0),L.current&&clearTimeout(L.current),q.current&&clearTimeout(q.current)}},[R]);const He=N(()=>{$(!0),b.current&&clearTimeout(b.current),b.current=window.setTimeout(()=>{$(!1)},1e3)},[$]),ye=N(()=>{const a=g.current;a&&Gr(a,c.current).catch(L=>{console.error(`Error attempting to toggle full-screen mode: ${L?.message} (${L?.name})`)})},[]),ve=N(()=>{c.current&&(c.current.paused?c.current.play().catch(()=>console.warn("Autoplay was prevented.")):(c.current.pause(),$(!0)))},[$]),oe=N(()=>{const a=c.current;if(!a)return;const L=l.current.mouse||l.current.keyboard;a.playbackRate=L?2:1},[]),le=N(a=>{l.current.mouse!==a&&(l.current.mouse=a,he(a||l.current.keyboard),oe())},[oe]),se=N(a=>{l.current.keyboard!==a&&(l.current.keyboard=a,he(l.current.mouse||a),oe())},[oe]),ue=N(a=>{c.current&&(c.current.currentTime+=a,E.current&&clearTimeout(E.current),E.current=setTimeout(()=>{R(!1,!0)},1500),$(!0))},[R,$]),be=N(()=>{if(!c.current)return;const a=!c.current.muted;c.current.muted=a,H(a),localStorage.setItem("playerMuted",String(a)),!a&&c.current.volume===0&&(c.current.volume=.5,V(.5),localStorage.setItem("playerVolume",String(.5))),$(!0)},[$]);M(()=>{const a=()=>c.current,L=Qr(a,q=>{z(q),q&&$(!0)});return z(ce(a())),L},[$]),M(()=>{const a=q=>{if(!q.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')){if(q.code==="Space"){if(q.preventDefault(),y.current)return;y.current=!0,_.current&&clearTimeout(_.current),_.current=window.setTimeout(()=>{_.current=null,y.current&&se(!0)},180);return}switch(q.key.toLowerCase()){case"f":ye();break;case"m":be();break;case"arrowright":ue(10);break;case"arrowleft":ue(-10);break;case"arrowup":if(q.preventDefault(),c.current){const F=Math.min(1,c.current.volume+.1);c.current.volume=F,V(F)}break;case"arrowdown":if(q.preventDefault(),c.current){const F=Math.max(0,c.current.volume-.1);c.current.volume=F,V(F)}break}}},L=q=>{if(q.code==="Space"){if(q.preventDefault(),y.current=!1,l.current.keyboard){se(!1);return}_.current&&(clearTimeout(_.current),_.current=null,ve())}};return document.addEventListener("keydown",a),document.addEventListener("keyup",L),()=>{document.removeEventListener("keydown",a),document.removeEventListener("keyup",L),_.current&&(clearTimeout(_.current),_.current=null),y.current=!1,se(!1),he(!1)}},[se,ve,ye,be,ue]),M(()=>{const a=j=>j?!!j.closest('[data-speed-boost-ignore="true"], [data-player-ui="true"], button, input, select, textarea, a, [role="button"], [role="slider"], [contenteditable="true"]'):!0,L=j=>{if(j.button!==0)return;const J=j.target;if(!J||a(J))return;const U=g.current;!U||!U.contains(J)||(d.current&&clearTimeout(d.current),d.current=window.setTimeout(()=>{d.current=null,le(!0)},180))},q=j=>{const J=j.target;if(!J||a(J))return;const U=g.current;!U||!U.contains(J)||(d.current&&clearTimeout(d.current),d.current=window.setTimeout(()=>{d.current=null,le(!0)},180))},p=()=>{d.current&&(clearTimeout(d.current),d.current=null),le(!1)},F=()=>{d.current&&(clearTimeout(d.current),d.current=null),y.current=!1,_.current&&(clearTimeout(_.current),_.current=null),se(!1),le(!1),he(!1)};return document.addEventListener("mousedown",L),document.addEventListener("mouseup",p),document.addEventListener("touchstart",q,{passive:!0}),document.addEventListener("touchend",p),document.addEventListener("touchcancel",p),document.addEventListener("pointerup",p),document.addEventListener("pointercancel",p),window.addEventListener("blur",F),()=>{document.removeEventListener("mousedown",L),document.removeEventListener("mouseup",p),document.removeEventListener("touchstart",q),document.removeEventListener("touchend",p),document.removeEventListener("touchcancel",p),document.removeEventListener("pointerup",p),document.removeEventListener("pointercancel",p),window.removeEventListener("blur",F),d.current&&(clearTimeout(d.current),d.current=null)}},[se,le]);const Ve=N(()=>{B(!0),G(!1),setTimeout(()=>R(!1,!0),50)},[R]),We=N(()=>{B(!0),G(!1)},[]),ze=N(()=>{const a=c.current;a&&!a.paused&&a.readyState>=3&&!a.seeking||G(!0)},[]),Ue=N(()=>{G(!1)},[]),Ke=N(()=>{B(!1),G(!1),$(!0),setTimeout(()=>R(!1,!0),50)},[R]),Xe=C(!1);Xe.current=me,M(()=>{if(!me)return;let a=c.current?.currentTime??0,L=0;const q=window.setInterval(()=>{const p=c.current;if(!p)return;L+=1;const F=p.currentTime,j=F!==a;if(a=F,!(p.paused||p.seeking)){if(j||p.readyState>=3){G(!1);return}L>=24&&p.readyState>=2&&!p.ended&&G(!1)}},500);return()=>window.clearInterval(q)},[me]),M(()=>{ie.current=!1,Ce.current=-1,S.current=0,k.current=Math.random().toString(36).substring(2),w(0),G(!1)},[r,t]);const Ge=N(()=>{w(0),G(!1)},[]);M(()=>{const a=k.current;return()=>{At(a)}},[r,t]),M(()=>{if(o!=="iframe")return;R(!1,!0);const a=setInterval(()=>{R(!1,!0)},6e4);return()=>clearInterval(a)},[o,R]);const Qe=N(()=>{w(c.current?.duration||0),oe()},[oe]),Ye=N(()=>{if(c.current){const a=c.current.muted,L=c.current.volume;H(a),V(L),localStorage.setItem("playerMuted",String(a)),localStorage.setItem("playerVolume",String(L))}},[]),Je=N(()=>{const a=c.current;if(!a)return;Xe.current&&!a.paused&&!a.seeking&&G(!1);const L=a.currentTime||0,q=Date.now();q-S.current>6e4&&R()&&(S.current=q);const p=e.find(F=>L>=F.start_time&&L<F.end_time)||null;Se(F=>F?.skip_id!==p?.skip_id?p:F),re&&p&&!a.paused&&(a.currentTime=p.end_time,Se(null))},[e,re,R]),Ze=N(()=>{const a=ge();a&&(a.currentTime=a.duration,tt.progress.updateProgress.mutate(a).then(()=>{f.invalidateQueries({queryKey:[de.videoSources,r,t]}),f.invalidateQueries({queryKey:[de.continueWatching]})}).catch(L=>console.error("Failed to send final progress:",L)))},[ge,f,r,t]),et=N(()=>{ie.current=!0,Ze()},[Ze]);M(()=>{const a=()=>{W&&(X(!1),u.current&&c.current?.play(),R(!1,!0))};return W&&(document.addEventListener("mouseup",a),document.addEventListener("pointerup",a),document.addEventListener("touchend",a),document.addEventListener("pointercancel",a),document.addEventListener("touchcancel",a)),()=>{document.removeEventListener("mouseup",a),document.removeEventListener("pointerup",a),document.removeEventListener("touchend",a),document.removeEventListener("pointercancel",a),document.removeEventListener("touchcancel",a)}},[W,R]);const Tt=pe(()=>({togglePlay:ve,seek:ue,toggleMute:be,toggleFullscreen:ye,onPlay:Ve,onPause:Ke,onLoadedMetadata:Qe,formatTime:It,onVolumeChange:Ye,onTimeUpdate:Je,onEnded:et,setShowControls:$,setIsScrubbing:X,setIsAutoSkipEnabled:lt,setCurrentSkipInterval:Se,setSubtitleFontSize:Ae,setSubtitlePosition:Ie,setSubtitleBgOpacity:Me,setSubtitleBgColor:$e,setSubtitleTextColor:Fe,setSubtitleEdge:De,setSubtitleBold:Re,setSubtitleStyle:je,setAvailableSubtitles:bt,setActiveSubtitleTrack:wt,setShowSettings:Ct,setShowVolumeSlider:Et,wasPlayingBeforeScrub:u,inactivityTimer:b,flashControls:He,setIsFullscreen:z,onWaiting:ze,onPlaying:We,onCanPlay:Ue,sendProgressUpdate:R,setUseNativeControls:Oe,resetMediaState:Ge}),[ve,ue,be,ye,Ve,Ke,Qe,Ye,Je,et,z,ze,We,Ue,R,Oe,Ge,He,je]);return{refs:{videoRef:c,playerContainerRef:g},state:{isPlaying:m,isMuted:P,volume:K,isFullscreen:T,duration:h,showControls:D,isScrubbing:W,isAutoSkipEnabled:re,currentSkipInterval:ut,subtitleFontSize:dt,subtitlePosition:ft,subtitleBgOpacity:pt,subtitleBgColor:mt,subtitleTextColor:ht,subtitleEdge:gt,subtitleBold:yt,availableSubtitles:vt,activeSubtitleTrack:_t,showSettings:St,showVolumeSlider:kt,isBuffering:me,isSpeedBoostActive:Lt,useNativeControls:xt},actions:Tt}};function Yr(){try{return typeof navigator<"u"&&/android/i.test(navigator.userAgent)}catch{return!1}}function Ho(e,r){const{refs:t,actions:s}=e,o=C(r);o.current=r;const i=C(!1),f=C(!1),v=c=>{try{if(c)return c.matches}catch{}try{return window.innerWidth>window.innerHeight}catch{return!1}};M(()=>{if(!Yr())return;let c=null;const g=()=>{const b=t.playerContainerRef.current;if(v(c)){if(!o.current||!b||ce(t.videoRef.current)||f.current)return;i.current=!0,s.toggleFullscreen()}else f.current=!1,i.current&&(i.current=!1,ce(t.videoRef.current)&&s.toggleFullscreen())};try{c=window.matchMedia("(orientation: landscape)"),c.addEventListener?c.addEventListener("change",g):c.addListener(g)}catch{}return g(),()=>{try{c&&(c.removeEventListener?c.removeEventListener("change",g):c.removeListener(g))}catch{}}},[s,t.playerContainerRef,t.videoRef,r]),M(()=>{const c=()=>{if(!ce(t.videoRef.current)){i.current=!1;try{window.matchMedia("(orientation: landscape)").matches&&(f.current=!0)}catch{f.current=!0}}};return document.addEventListener("fullscreenchange",c),document.addEventListener("webkitfullscreenchange",c),()=>{document.removeEventListener("fullscreenchange",c),document.removeEventListener("webkitfullscreenchange",c)}},[t.videoRef])}const Jr=e=>Math.max(8,Math.min(40,Math.ceil(e/16.7)+4));function Vo({videoRef:e,canvasRef:r,delayMs:t,enabled:s}){const o=C(t);o.current=t;const i=C([]),f=C(-1),v=C(-1),c=C(!1),g=C(0),b=C(null);M(()=>{const u=y=>{if(y)try{y.close()}catch{}},E=()=>{for(const y of i.current)u(y.bitmap);i.current=[]};if(!s){E(),f.current=-1,v.current=-1,c.current=!1,g.current=0;return}let S=!1;const l=()=>{b.current!==null&&(cancelAnimationFrame(b.current),b.current=null)},d=()=>{S||(l(),b.current=requestAnimationFrame(()=>{_()}))};async function _(){if(S)return;const y=e.current,k=r.current;if(!y||!k||y.videoWidth===0){d();return}if(y.paused||y.ended||document.hidden||y.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){d();return}const m=y.getVideoPlaybackQuality().totalVideoFrames;if(m===f.current){d();return}(y.seeking||v.current>=0&&Math.abs(y.currentTime-v.current)>.5)&&(E(),c.current=!1,g.current=0,f.current=-1),v.current=y.currentTime,(k.width!==y.videoWidth||k.height!==y.videoHeight)&&(k.width=y.videoWidth,k.height=y.videoHeight);const B=Math.max(0,o.current||0);B>g.current&&(c.current=!1);try{const P=await createImageBitmap(y);if(S){u(P);return}f.current=m;const H=performance.now(),K=k.getContext("2d"),V=w=>{K&&K.drawImage(w,0,0,k.width,k.height)};if(B<=0){E(),c.current=!1,g.current=0,V(P),u(P),d();return}const T=i.current;T.push({bitmap:P,capture:H});const z=Jr(B);for(;T.length>z;)u(T.shift()?.bitmap);let h=-1;for(let w=T.length-1;w>=0;w--)if(H-T[w].capture>=B){h=w;break}if(h!==-1){for(let D=0;D<h;D++)u(T.shift()?.bitmap);const w=T.shift();w?(V(w.bitmap),u(w.bitmap),c.current=!0,g.current=B):V(P)}else if(!c.current)V(P);else{const w=T.shift();w?(V(w.bitmap),u(w.bitmap)):V(P)}}catch{}d()}return d(),()=>{S=!0,l();for(const y of i.current)try{y.bitmap.close()}catch{}i.current=[]}},[s,e,r])}const rt=(e,r)=>{try{localStorage.setItem("playerVideoDelayMs",String(e)),localStorage.setItem("playerVideoDelayEnabled",String(r))}catch{}},ot=e=>{try{localStorage.setItem("playerVideoDelayEnabled",String(e))}catch{}};function Wo(e,r){const[t,s]=x(()=>{try{const m=Number(localStorage.getItem("playerVideoDelayMs"));if(Number.isFinite(m)&&m>=0&&m<=500)return Math.round(m)}catch{}return 180}),[o,i]=x(()=>{try{return localStorage.getItem("playerVideoDelayEnabled")==="true"}catch{return!1}}),[f,v]=x(!1),[c,g]=x(!1),b=C(null),u=C(null),E=m=>{const B=Math.max(0,Math.min(500,Math.round(m)));s(B);try{localStorage.setItem("playerVideoDelayMs",String(B))}catch{}},S=m=>{i(m),ot(m)},l=N(()=>{g(!1),v(!1)},[]);return{videoDelayMs:t,videoDelayEnabled:o,setDelayEnabled:S,handleVideoDelayChange:E,isCalibrating:f,testClipActive:c,stopCalibration:l,openAvSyncCalibrator:()=>{b.current={enabled:o,ms:t},i(!0),ot(!0),r?.(),v(!0)},cancelAvSyncCalibrator:()=>{const m=b.current;b.current=null,m&&(s(m.ms),i(m.enabled),rt(m.ms,m.enabled)),g(!1),v(!1)},applyAvSyncCalibrator:()=>{b.current=null,i(!0),rt(t,!0),g(!1),v(!1)},toggleTestClip:()=>{if(c){g(!1);return}const m=e.current;m&&!isNaN(m.currentTime)&&(u.current=m.currentTime),g(!0)},calibReturnRef:u,effectiveVideoDelayMs:o?t:0}}function zo(){const[e,r]=x(()=>{try{return localStorage.getItem("playerTheaterMode")==="true"}catch{return!1}});M(()=>{try{e?document.body.classList.add("theater-mode"):document.body.classList.remove("theater-mode")}catch(o){console.error(o)}return()=>{try{document.body.classList.remove("theater-mode")}catch(o){console.error(o)}}},[e]);const t=N(()=>{r(o=>{const i=!o;try{localStorage.setItem("playerTheaterMode",i.toString())}catch{}return i})},[]),s=N(o=>{if(e&&o.target===o.currentTarget){r(!1);try{localStorage.setItem("playerTheaterMode","false")}catch{}}},[e]);return{isTheaterMode:e,toggleTheaterMode:t,handleLayoutClick:s}}const te={enabled:!0,blur:60,saturation:150,brightness:70,opacity:60};function Zr(){try{const e=localStorage.getItem("playerAmbientLight");if(!e)return te;const r=JSON.parse(e),t=(s,o,i,f)=>{const v=Number(s);return Number.isFinite(v)?Math.max(i,Math.min(f,v)):o};return{enabled:r.enabled??te.enabled,blur:t(r.blur,te.blur,0,120),saturation:t(r.saturation,te.saturation,0,200),brightness:t(r.brightness,te.brightness,20,120),opacity:t(r.opacity,te.opacity,10,100)}}catch{return te}}function Uo(){const[e,r]=x(Zr),t=N(s=>{r(o=>{const i={...o,...s};try{localStorage.setItem("playerAmbientLight",JSON.stringify(i))}catch{}return i})},[]);return{settings:e,update:t}}const eo="_theaterAmbient_x9t0o_1",to={theaterAmbient:eo},Le=160,xe=90,no=120,Ko=({videoRef:e,active:r,settings:t,className:s})=>{const o=C(null);return M(()=>{if(!r)return;const i=o.current,f=e.current;if(!i||!f)return;const v=i.getContext("2d",{alpha:!1});if(!v)return;let c=0,g=0,b=!1;const u=()=>{if(!(f.readyState<2||!f.videoWidth))try{const l=f.videoWidth,d=f.videoHeight,_=Le/xe,y=l/d;let k=l,m=d,B=0,P=0;y>_?(k=d*_,B=(l-k)/2):(m=l/_,P=(d-m)/2),v.drawImage(f,B,P,k,m,0,0,Le,xe)}catch{}},E=l=>{b||f.paused||(c=requestAnimationFrame(E),!(l-g<no)&&(g=l,u()))},S=()=>{b||(cancelAnimationFrame(c),g=0,c=requestAnimationFrame(E))};return f.addEventListener("play",S),f.addEventListener("seeked",u),f.addEventListener("loadeddata",u),c=requestAnimationFrame(E),()=>{b=!0,cancelAnimationFrame(c),f.removeEventListener("play",S),f.removeEventListener("seeked",u),f.removeEventListener("loadeddata",u)}},[r,e]),r?n("canvas",{ref:o,width:Le,height:xe,"aria-hidden":"true",className:s??to.theaterAmbient,style:{filter:`blur(${t.blur}px) saturate(${t.saturation}%) brightness(${t.brightness}%)`,opacity:t.opacity/100}}):null},ro="_row_1fq55_1",oo="_rowHeader_1fq55_9",so="_rowLabel_1fq55_17",ao="_rowValue_1fq55_28",co="_slider_1fq55_36",io="_swatches_1fq55_99",lo="_swatch_1fq55_99",uo="_swatchPicked_1fq55_114",fo="_colorInput_1fq55_120",po="_segmented_1fq55_131",O={row:ro,rowHeader:oo,rowLabel:so,rowValue:ao,slider:co,swatches:io,swatch:lo,swatchPicked:uo,colorInput:fo,segmented:po},mo=({label:e,display:r,min:t,max:s,step:o,value:i,percent:f,onChange:v,onCommit:c})=>n("div",{className:O.row,children:[n("div",{className:O.rowHeader,children:[n("span",{className:O.rowLabel,children:e}),n("span",{className:O.rowValue,children:r})]}),n("input",{type:"range",className:O.slider,min:t,max:s,step:o,value:i,"aria-label":e,"data-speed-boost-ignore":"true",onInput:g=>v(Number(g.target.value)),onMouseDown:g=>g.stopPropagation(),onPointerDown:g=>g.stopPropagation(),onTouchStart:g=>g.stopPropagation(),onPointerUp:c,onPointerCancel:c,onTouchEnd:c,onKeyUp:c,onBlur:c,style:{"--slider-percent":`${f}%`}})]}),Xo=({label:e,colors:r,value:t,onChange:s})=>n("div",{className:O.row,children:[n("div",{className:O.rowHeader,children:n("span",{className:O.rowLabel,children:e})}),n("div",{className:O.swatches,children:[r.map(o=>n("button",{type:"button","aria-label":`${e} ${o}`,"aria-pressed":t.toLowerCase()===o.toLowerCase(),onClick:()=>s(o),className:`${O.swatch} ${t.toLowerCase()===o.toLowerCase()?O.swatchPicked:""}`,style:{backgroundColor:o}},o)),n("input",{type:"color","aria-label":`Custom ${e.toLowerCase()}`,className:O.colorInput,value:t,"data-speed-boost-ignore":"true",onInput:o=>s(o.target.value),onMouseDown:o=>o.stopPropagation(),onPointerDown:o=>o.stopPropagation(),onTouchStart:o=>o.stopPropagation()})]})]});function Go({label:e,options:r,value:t,onChange:s}){return n("div",{className:O.row,children:[n("div",{className:O.rowHeader,children:n("span",{className:O.rowLabel,children:e})}),n("div",{className:O.segmented,role:"group","aria-label":e,children:r.map(o=>n("button",{type:"button","aria-pressed":t===o,onClick:()=>s(o),children:[n("span",{children:o}),t===o&&n(Y,{name:"check",size:10})]},o))})]})}const we=10,Pe=500,Te=e=>Math.max(0,Math.min(Pe,Math.round(e))),Qo=({isOpen:e,ms:r,onChange:t,onApply:s,onClose:o,testClipActive:i,onTestClip:f})=>e?n("div",{role:"dialog","aria-label":"Calibrate audio video sync","data-speed-boost-ignore":"true",onClick:v=>v.stopPropagation(),style:{position:"absolute",right:8,bottom:112,width:"min(260px, calc(100% - 16px))",maxHeight:"calc(100% - 124px)",overflowY:"auto",overflowX:"hidden",zIndex:60,display:"flex",flexDirection:"column",alignItems:"center",gap:8,padding:12,borderRadius:"var(--radius-lg)",border:"1px solid var(--glass-border)",background:"rgba(18, 18, 22, 0.95)",boxShadow:"var(--glass-shadow)",backdropFilter:"blur(14px)",WebkitBackdropFilter:"blur(14px)",boxSizing:"border-box"},children:[n("div",{style:{fontSize:"0.8rem",fontWeight:800,color:"var(--text-primary)"},children:"A/V sync"}),n("div",{children:n(ne,{size:"sm",variant:"secondary",onClick:f,children:i?"Back to video":"Preview test clip"})}),n("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:6,flexWrap:"wrap"},children:[n(ne,{size:"sm",onClick:()=>t(Te(r-we)),"aria-label":"Decrease delay by 10 milliseconds",children:["− ",we,"ms"]}),n("div",{style:{fontSize:"1.1rem",fontWeight:800,minWidth:64,textAlign:"center"},children:[r,"ms"]}),n(ne,{size:"sm",onClick:()=>t(Te(r+we)),"aria-label":"Increase delay by 10 milliseconds",children:["+ ",we,"ms"]})]}),n(mo,{label:"Video delay",display:`${r}ms`,min:0,max:Pe,step:5,value:r,percent:r/Pe*100,onChange:v=>t(Te(v))}),n("div",{style:{display:"flex",gap:8,justifyContent:"center",flexWrap:"wrap"},children:[n(ne,{size:"sm",variant:"secondary",onClick:o,children:"Cancel"}),n(ne,{size:"sm",onClick:s,children:["Apply ",r,"ms"]})]})]}):null;export{Ko as A,Lo as B,Po as C,Z as D,Do as E,te as F,mo as M,Fo as P,Bo as R,Ao as S,Eo as T,Io as U,Mo as a,qo as b,jo as c,wo as d,So as e,xo as f,No as g,ko as h,Wo as i,Vo as j,zo as k,Ho as l,Uo as m,_o as n,Nr as o,$o as p,bo as q,Co as r,or as s,ae as t,Oo as u,Qo as v,Ro as w,To as x,Xo as y,Go as z};
@@ -1 +0,0 @@
1
- import{u as e,S as s,d as y,h as g}from"./vendor-core-DfaOB3Rn.js";import{I as p}from"./vendor-icons-DrybRNxP.js";import{M as l,y as m,T as S,B as f,z as k,D as x,F as N}from"./AvSyncCalibrator-C5GxpyPE.js";const C=({classes:o,title:t,titleTag:i="span",showBack:a=!0,onBack:n,panelRef:b,onPanelClick:r,children:c})=>{const d=i;return e("div",{ref:b,className:o.panel,onClick:r,"data-speed-boost-ignore":"true",children:[e("div",{className:o.header,children:[a&&e("button",{className:o.backBtn,onClick:n,children:e(p,{name:"chevron-left"})}),e(d,{className:o.title||void 0,children:t})]}),e("div",{className:o.content,children:c})]})},$=({classes:o,values:t,onChange:i})=>{const a=()=>{const n=x;i("fontSize",n.fontSize),i("position",n.position),i("bgOpacity",n.bgOpacity),i("bgColor",n.bgColor),i("textColor",n.textColor),i("edge",n.edge),i("bold",n.bold)};return e(s,{children:[e(l,{label:"Font Size",display:t.fontSize.toFixed(1),min:.5,max:10,step:.5,value:t.fontSize,percent:(t.fontSize-.5)/9.5*100,onChange:n=>{Number.isFinite(n)&&i("fontSize",n)}}),e(l,{label:"Vertical Position",display:`${t.position}`,min:0,max:100,step:1,value:t.position,percent:t.position,onChange:n=>{Number.isFinite(n)&&i("position",Math.round(n))}}),e(l,{label:"Background Opacity",display:`${Math.round(t.bgOpacity*100)}%`,min:0,max:1,step:.05,value:t.bgOpacity,percent:t.bgOpacity*100,onChange:n=>{Number.isFinite(n)&&i("bgOpacity",n)}}),e(m,{label:"Text Color",colors:S,value:t.textColor,onChange:n=>i("textColor",n)}),e(m,{label:"Background Color",colors:f,value:t.bgColor,onChange:n=>i("bgColor",n)}),e(k,{label:"Text Edge",options:["shadow","outline","none"],value:t.edge,onChange:n=>i("edge",n)}),e("button",{type:"button",className:`${o.item} ${t.bold?o.active:""}`,onClick:()=>i("bold",!t.bold),children:[e("span",{children:"Bold Text"}),t.bold&&e(p,{name:"check",size:12})]}),e("button",{type:"button",className:o.item,onClick:a,children:e("span",{children:"Reset to Defaults"})})]})},z=({classes:o,enabled:t,delayMs:i,onToggle:a,onDelayChange:n,onCalibrate:b})=>{const[r,c]=y(null),d=r??i;g(()=>{c(null)},[i]);const h=()=>{r!==null&&(n(r),c(null))};return e(s,{children:[e("button",{type:"button",className:`${o.item} ${t?o.active:""}`,onClick:()=>a(!t),children:[e("span",{children:"Video delay"}),t&&e(p,{name:"check",size:12})]}),e(l,{label:"Video delay",display:`${d}ms`,min:0,max:500,step:5,value:d,percent:d/500*100,onChange:u=>c(Math.round(u)),onCommit:h}),e("div",{className:o.note,children:"For Bluetooth headsets where audio arrives late. Video is held back via canvas; audio plays untouched."}),b&&e("button",{type:"button",className:o.item,onClick:b,children:e("span",{children:"Calibrate…"})})]})},B=({classes:o,values:t,onChange:i})=>e(s,{children:[e("button",{type:"button",className:`${o.item} ${t.enabled?o.active:""}`,onClick:()=>i({enabled:!t.enabled}),"aria-pressed":t.enabled,children:[e("span",{children:"Ambient light"}),e("span",{style:{display:"flex",alignItems:"center",gap:6},children:[t.enabled?"On":"Off",t.enabled&&e(p,{name:"check",size:12})]})]}),e(l,{label:"Blur",display:`${t.blur}px`,min:0,max:120,step:2,value:t.blur,percent:t.blur/120*100,onChange:a=>i({blur:Math.round(a)})}),e(l,{label:"Saturation",display:`${t.saturation}%`,min:0,max:200,step:5,value:t.saturation,percent:t.saturation/200*100,onChange:a=>i({saturation:Math.round(a)})}),e(l,{label:"Brightness",display:`${t.brightness}%`,min:20,max:120,step:5,value:t.brightness,percent:(t.brightness-20)/100*100,onChange:a=>i({brightness:Math.round(a)})}),e(l,{label:"Opacity",display:`${t.opacity}%`,min:10,max:100,step:5,value:t.opacity,percent:(t.opacity-10)/90*100,onChange:a=>i({opacity:Math.round(a)})}),e("div",{className:o.note,children:"Mirrors the video onto the backdrop behind the player. Turn off for pure black."}),e("button",{type:"button",className:o.item,onClick:()=>i({...N}),children:e("span",{children:"Reset to defaults"})})]}),E=({classes:o,options:t,onSelect:i})=>e(s,{children:t.map(a=>e("button",{type:"button",className:`${o.item} ${a.selected?o.active:""}`,onClick:()=>i(a.key),children:[e("span",{children:a.label}),a.selected&&e(p,{name:"check",size:12})]},a.key))});export{z as A,E as O,C as S,$ as a,B as b};