@serifpersia/dango 3.8.3 → 3.8.5

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 (90) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-Dc6uPr1B.js → AnimeCard-CkomfiIw.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-BkT4v_EB.js → AnimeInfo-CtBg9n1W.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-CvGOUt7G.js → AnimeInfoPage-DYic1q9k.js} +2 -2
  5. package/client/dist/assets/{Asmr-CaO_2wxo.js → Asmr-VRahW3BN.js} +2 -2
  6. package/client/dist/assets/AsmrPopup-Du6eR09X.js +1 -0
  7. package/client/dist/assets/AsmrResetProgressModal-CBz6OxDc.js +1 -0
  8. package/client/dist/assets/Home-BQK51s69.js +1 -0
  9. package/client/dist/assets/Home-grKghNM9.css +1 -0
  10. package/client/dist/assets/Insights-2Ei1ZfVV.js +1 -0
  11. package/client/dist/assets/Insights-DEicrokg.css +1 -0
  12. package/client/dist/assets/{LibraryListPage-0IybQgPU.js → LibraryListPage-BJ7o8MNw.js} +1 -1
  13. package/client/dist/assets/ListeningList-C_hDyuFM.js +1 -0
  14. package/client/dist/assets/{Manga-B4p5dXe8.js → Manga-4XqXRRq7.js} +1 -1
  15. package/client/dist/assets/{MangaInfoPage-DR2_2eve.js → MangaInfoPage-BSj5R5c3.js} +1 -1
  16. package/client/dist/assets/{MangaReadPage-CC72GY9L.js → MangaReadPage-BpJNfRcn.js} +1 -1
  17. package/client/dist/assets/{MangaResetProgressModal-ojbIsaI7.js → MangaResetProgressModal-B1DyEkSk.js} +1 -1
  18. package/client/dist/assets/{Mature-C1PCMe3g.js → Mature-eyCcjCLK.js} +1 -1
  19. package/client/dist/assets/{MatureConsentModal-BTJloHUV.js → MatureConsentModal-J7mF0tSH.js} +1 -1
  20. package/client/dist/assets/MediaCard-CJ-18Ma8.css +1 -0
  21. package/client/dist/assets/MediaCard-Wp1bAPsS.js +1 -0
  22. package/client/dist/assets/{OptionListMenu-CFBJv5e-.js → OptionListMenu-oRSmXUYN.js} +1 -1
  23. package/client/dist/assets/Player-1LfYnRyR.css +1 -0
  24. package/client/dist/assets/Player-D3cSsrYy.js +56 -0
  25. package/client/dist/assets/{PlayerProvider-DjIXyFBk.js → PlayerProvider-WO2tWEb1.js} +1 -1
  26. package/client/dist/assets/PlayerSettings-CbGkvNJq.css +1 -0
  27. package/client/dist/assets/{PlayerSettings-B37kxh6A.js → PlayerSettings-CfTMIrw1.js} +1 -1
  28. package/client/dist/assets/{QueueOptionsButton-D0LpFAJe.js → QueueOptionsButton-BeAS9Ufo.js} +1 -1
  29. package/client/dist/assets/QueueRail-BrVL0OWm.js +1 -0
  30. package/client/dist/assets/QueueRail-CcHdXRmS.css +1 -0
  31. package/client/dist/assets/{ReadingList-B6pULeSS.js → ReadingList-BWT_0y7B.js} +1 -1
  32. package/client/dist/assets/{ResetProgressModal-Dq6yudb6.js → ResetProgressModal-D9Hi4yvU.js} +1 -1
  33. package/client/dist/assets/{Search-B2C2_KM4.js → Search-Ma_U--_p.js} +1 -1
  34. package/client/dist/assets/Settings-B57LhIVH.css +1 -0
  35. package/client/dist/assets/Settings-BWXmAzt8.js +21 -0
  36. package/client/dist/assets/{SkeletonGrid-TIfa7-R8.js → SkeletonGrid-Bi4N7XcX.js} +1 -1
  37. package/client/dist/assets/Trackers-BC636V59.css +1 -0
  38. package/client/dist/assets/Trackers-CyZCgKDv.js +2 -0
  39. package/client/dist/assets/{Tv-BNc7ujCX.js → Tv-3U6AQcKB.js} +1 -1
  40. package/client/dist/assets/{TvInfo-k9u9Pxa3.js → TvInfo-C6k13aZL.js} +1 -1
  41. package/client/dist/assets/{TvPopup-e7OkKs6q.js → TvPopup-CSFfDhV6.js} +1 -1
  42. package/client/dist/assets/{TvSearch-BP-0VIrE.js → TvSearch-BlrNDENc.js} +1 -1
  43. package/client/dist/assets/{TvWatchlist-Yv8Qc4lj.js → TvWatchlist-l6N6tOjK.js} +1 -1
  44. package/client/dist/assets/VirtualKeyboard-CG5L_RyF.js +1 -0
  45. package/client/dist/assets/VirtualKeyboard-CejCi3pJ.css +1 -0
  46. package/client/dist/assets/{WatchAlong-Dt5_kNJg.js → WatchAlong-KYPcweoT.js} +1 -1
  47. package/client/dist/assets/{WatchAlongPanel-DTjl8tog.js → WatchAlongPanel-CdJRfBiU.js} +1 -1
  48. package/client/dist/assets/{Watchlist-BvbY9oBd.js → Watchlist-Bwh35S5A.js} +1 -1
  49. package/client/dist/assets/index-BKQMKYFa.css +1 -0
  50. package/client/dist/assets/index-fS4AGBy2.js +178 -0
  51. package/client/dist/assets/{libraryInvalidation-BirscVrS.js → libraryInvalidation-C4kz8swK.js} +1 -1
  52. package/client/dist/assets/{playbackCompletion-C8izYMOL.js → playbackCompletion-Dfy-xXLg.js} +1 -1
  53. package/client/dist/assets/{useAnimeInfoData-C60IXLN5.js → useAnimeInfoData-D7YFegdk.js} +1 -1
  54. package/client/dist/assets/useAsmrPopup-BBmHrx9v.js +1 -0
  55. package/client/dist/assets/{useMangaLibrary-ClgxldD8.js → useMangaLibrary-4UsX_okY.js} +1 -1
  56. package/client/dist/assets/{useMangaPopup-D4ItPSfW.js → useMangaPopup-DrrvSchc.js} +1 -1
  57. package/client/dist/assets/{useProviders-DVv7j4AK.js → useProviders-SXQCnsGW.js} +1 -1
  58. package/client/dist/assets/{useTv-BUu6RG6F.js → useTv-EwO7nOqH.js} +1 -1
  59. package/client/dist/assets/{useTvLibrary-DnKiDhxZ.js → useTvLibrary-D6KqZu5s.js} +1 -1
  60. package/client/dist/assets/useWatchAlongPlayer-CJebxcje.css +1 -0
  61. package/client/dist/assets/useWatchAlongPlayer-DC-nsje5.js +10 -0
  62. package/client/dist/index.html +2 -2
  63. package/package.json +2 -2
  64. package/server/dist/server.js +144 -144
  65. package/server/package.json +1 -1
  66. package/client/dist/assets/AsmrResetProgressModal-h35ZX9OW.js +0 -1
  67. package/client/dist/assets/Home-CHKpLQLZ.js +0 -1
  68. package/client/dist/assets/Home-DINyLUCh.css +0 -1
  69. package/client/dist/assets/Insights-CA_1302g.js +0 -1
  70. package/client/dist/assets/Insights-D0qrep0K.css +0 -1
  71. package/client/dist/assets/ListeningList-Cn1z8o3k.js +0 -1
  72. package/client/dist/assets/MediaCard-CoyScn-7.css +0 -1
  73. package/client/dist/assets/MediaCard-wcV5T3yJ.js +0 -1
  74. package/client/dist/assets/Player-D-sQfjcx.css +0 -1
  75. package/client/dist/assets/Player-MJJ6fHc4.js +0 -56
  76. package/client/dist/assets/PlayerSettings-BXGe3F5k.css +0 -1
  77. package/client/dist/assets/QueueRail-Bkh4VZls.css +0 -1
  78. package/client/dist/assets/QueueRail-D4qxAKBU.js +0 -1
  79. package/client/dist/assets/Settings-D37LNfis.css +0 -1
  80. package/client/dist/assets/Settings-DQHfH5Ba.js +0 -21
  81. package/client/dist/assets/Trackers-ChrW-D2i.js +0 -2
  82. package/client/dist/assets/Trackers-CvO6aWVx.css +0 -1
  83. package/client/dist/assets/VirtualKeyboard-BaUll8Yv.css +0 -1
  84. package/client/dist/assets/VirtualKeyboard-Cqj3Id2l.js +0 -1
  85. package/client/dist/assets/index-BR99iwWT.js +0 -178
  86. package/client/dist/assets/index-CoCvEAx6.css +0 -1
  87. package/client/dist/assets/useAsmr-yVlXiVJj.js +0 -1
  88. package/client/dist/assets/useAsmrPopup-Do0bqxew.js +0 -1
  89. package/client/dist/assets/useWatchAlongPlayer-1fbftVwT.css +0 -1
  90. package/client/dist/assets/useWatchAlongPlayer-hjLY2hHu.js +0 -10
@@ -0,0 +1 @@
1
+ ._sectionCard_1vuib_1{padding:0 0 var(--space-6);border-bottom:1px solid var(--border-secondary)}._sectionCard_1vuib_1 h3{margin:0 0 var(--space-3);font-size:var(--font-size-base);font-weight:700;color:var(--text-primary)}._sectionCard_1vuib_1 p{margin:0 0 var(--space-3);font-size:var(--font-size-sm);color:var(--text-secondary);line-height:1.5}._dangerCard_1vuib_20{padding:var(--space-5);border:1px solid color-mix(in srgb,var(--color-danger) 40%,transparent);border-radius:var(--radius-lg);background:color-mix(in srgb,var(--color-danger) 4%,transparent)}._dangerCard_1vuib_20 h3{color:var(--color-danger)}._settingRow_1vuib_31{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);padding:var(--space-3) 0;border-bottom:1px solid var(--border-secondary)}._settingRow_1vuib_31:last-child{border-bottom:none}._settingRow_1vuib_31 label{display:flex;flex-direction:column;gap:var(--space-1);font-size:var(--font-size-sm);color:var(--text-primary)}._title-preference-container_sdqgs_1{margin-bottom:var(--space-6);padding:var(--space-4);border:1px solid var(--border-primary);border-radius:var(--radius-md);background-color:var(--bg-tertiary)}._title-preference-container_sdqgs_1 h4{margin-top:0;margin-bottom:var(--space-4);color:var(--text-primary);font-size:var(--font-size-base);font-weight:var(--font-weight-semibold)}._error_sdqgs_17{color:var(--danger)}._toggle-button_sdqgs_21{position:relative;width:200px;height:40px;background:linear-gradient(135deg,var(--accent) 0%,var(--accent-dark) 100%);border:none;border-radius:20px;cursor:pointer;overflow:hidden;display:flex;align-items:center;justify-content:center;color:var(--accent-text);font-size:var(--font-size-base);font-weight:var(--font-weight-semibold);transition:var(--transition-base);box-shadow:var(--shadow-md)}._toggle-button_sdqgs_21:hover:not(:disabled){transform:translateY(-2px);box-shadow:var(--shadow-lg);filter:brightness(1.1)}._toggle-button_sdqgs_21:disabled{opacity:.7;cursor:not-allowed}._toggle-label_sdqgs_51{position:absolute;white-space:nowrap;transition:var(--transition-base)}._settingsHeader_gfwoa_1{margin-bottom:var(--space-8);animation:_fadeIn_gfwoa_1 .8s var(--ease-smooth)}._pageTitle_gfwoa_6{font-size:var(--font-size-xl);font-weight:800;color:var(--text-primary);margin:0 0 var(--space-2);letter-spacing:-.02em}._pageSubtitle_gfwoa_14{color:var(--text-tertiary);font-size:var(--font-size-sm);margin:0}._settingsLayout_gfwoa_20{display:flex;gap:var(--space-8);align-items:flex-start;animation:_slideUpIn_gfwoa_1 .8s var(--ease-smooth)}._sidebar_gfwoa_27{width:240px;display:flex;flex-direction:column;gap:var(--space-2);position:relative}._sidebarIndicator_gfwoa_35{position:absolute;left:0;right:0;border-radius:var(--radius-lg);background:var(--accent);transition:top .22s cubic-bezier(.2,1.2,.3,1),height .22s cubic-bezier(.2,1.2,.3,1),left .22s cubic-bezier(.2,1.2,.3,1),width .22s cubic-bezier(.2,1.2,.3,1);z-index:0;pointer-events:none}._sidebarItem_gfwoa_50{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-5);background:transparent;border:1px solid transparent;border-radius:var(--radius-lg);color:var(--text-tertiary);font-weight:600;font-size:var(--font-size-sm);cursor:pointer;transition:color .22s ease;text-align:left;position:relative;z-index:1}._sidebarItem_gfwoa_50:hover{color:var(--text-primary)}._sidebarItem_gfwoa_50._active_gfwoa_72{color:var(--accent-text)}._sidebarItem_gfwoa_50 svg{font-size:1.1rem}._mainContent_gfwoa_80{flex:1;min-width:0}._tabContent_gfwoa_85{display:flex;flex-direction:column;gap:var(--space-6);animation:_tabFadeIn_gfwoa_1 .3s ease}@keyframes _tabFadeIn_gfwoa_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}._settingItem_gfwoa_103{border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._shortcutContainer_gfwoa_108{display:flex;flex-direction:column;gap:var(--space-4);margin-top:var(--space-3)}._shortcutGroup_gfwoa_115{display:flex;flex-direction:column;gap:var(--space-2)}._shortcutGroupTitle_gfwoa_121{margin:0;color:var(--text-tertiary);font-size:.72rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em}._shortcutGrid_gfwoa_130{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:6px}._shortcutCard_gfwoa_136{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:5px 10px;background:#ffffff08;border:1px solid var(--border-primary);border-radius:var(--radius-md);font-size:var(--font-size-xs);color:var(--text-secondary);transition:all var(--transition-fast)}._shortcutCard_gfwoa_136:hover{background:#ffffff0f;border-color:var(--border-secondary);color:var(--text-primary)}._shortcutCard_gfwoa_136 kbd{display:inline-flex;align-items:center;padding:2px 6px;border:1px solid var(--border-secondary);border-radius:var(--radius-sm);background:var(--bg-tertiary);color:var(--text-primary);font:inherit;font-weight:600;font-size:.72rem;white-space:nowrap}._controls_gfwoa_170{display:flex;gap:var(--space-4);flex-wrap:wrap}._status_gfwoa_176{margin-top:var(--space-4);padding:var(--space-3) var(--space-4);background:color-mix(in srgb,var(--accent) 10%,transparent);border-radius:var(--radius-md);color:var(--accent-light);font-size:var(--font-size-sm);font-weight:500}@keyframes _fadeIn_gfwoa_1{0%{opacity:0}to{opacity:1}}@keyframes _slideUpIn_gfwoa_1{0%{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}@media(max-width:900px){._settingsLayout_gfwoa_20{flex-direction:column}._sidebar_gfwoa_27{width:100%;flex-direction:row;overflow-x:auto;padding-bottom:var(--space-2)}._sidebarIndicator_gfwoa_35{right:auto;top:auto!important;bottom:0;height:3px!important}._sidebarItem_gfwoa_50{padding:var(--space-3) var(--space-4);white-space:nowrap;flex-shrink:0}._sidebarItem_gfwoa_50 span{display:block}}@media(max-width:480px){._sidebarItem_gfwoa_50 span{display:none}._sidebarItem_gfwoa_50{padding:var(--space-4);justify-content:center}._shortcutGrid_gfwoa_130{grid-template-columns:1fr}}._sectionCard_tm30b_1{background:var(--glass-bg);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);padding:var(--space-8);border-radius:var(--radius-xl);box-shadow:var(--glass-shadow)}._title_tm30b_11{margin:0 0 var(--space-2);font-size:var(--font-size-lg);font-weight:700;color:var(--text-primary)}._signIn_tm30b_18{color:var(--text-secondary);font-size:var(--font-size-sm);margin:0 0 var(--space-6);line-height:1.6}._userInfo_tm30b_25{padding:var(--space-4) var(--space-5);background:color-mix(in srgb,var(--color-success) 5%,transparent);border:1px solid color-mix(in srgb,var(--color-success) 20%,transparent);border-radius:var(--radius-lg);margin-bottom:var(--space-6);display:flex;align-items:center;justify-content:space-between;gap:var(--space-4)}._userInfo_tm30b_25 p{margin:0;color:var(--text-secondary);font-size:var(--font-size-sm)}._userInfo_tm30b_25 strong{color:var(--color-success)}._warning_tm30b_47{color:var(--color-warning);font-size:var(--font-size-xs);margin:var(--space-3) 0 0;font-weight:500}._formGroup_tm30b_54{margin-bottom:var(--space-5)}._label_tm30b_58{display:block;margin-bottom:var(--space-2);color:var(--text-tertiary);font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em}._inputWrapper_tm30b_68{display:flex;gap:var(--space-2)}._input_tm30b_68{flex-grow:1;height:48px;padding:0 var(--space-4);background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-primary);border-radius:var(--radius-lg);font-size:var(--font-size-base);transition:all var(--transition-fast)}._input_tm30b_68:focus{outline:none;border-color:var(--accent);background:var(--bg-elevated);box-shadow:0 0 0 4px var(--accent-glow)}._select_tm30b_92{flex-grow:1;height:48px;padding:0 var(--space-4);background:var(--bg-tertiary);color:var(--text-primary);border:1px solid var(--border-primary);border-radius:var(--radius-lg);font-size:var(--font-size-base);cursor:pointer;transition:all var(--transition-fast);appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%2371717a' stroke-width='2' viewBox='0 0 12 12'%3E%3Cpolyline points='3 5 6 8 9 5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 1rem center}._actions_tm30b_109{display:flex;gap:var(--space-3);margin-top:var(--space-6);border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._hr_tm30b_117{border:none;border-top:1px solid var(--border-primary);margin:var(--space-8) 0}@media(max-width:600px){._userInfo_tm30b_25{flex-direction:column;align-items:flex-start}._actions_tm30b_109{flex-direction:column}}._settingItem_3qq0n_1{border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._modalOverlay_3qq0n_6{position:fixed;inset:0;background:#0009;display:flex;align-items:center;justify-content:center;z-index:1000;padding:var(--space-4)}._modal_3qq0n_6{background:var(--bg-secondary, #1a1a2e);border:1px solid var(--glass-border);border-radius:var(--radius-xl);padding:var(--space-8);max-width:420px;width:100%;box-shadow:var(--glass-shadow)}._modal_3qq0n_6 h4{margin:0 0 var(--space-2);font-size:var(--font-size-lg);font-weight:700;color:var(--text-primary)}._modal_3qq0n_6 p{color:var(--text-secondary);font-size:var(--font-size-sm);line-height:1.6;margin:0 0 var(--space-6)}._modalActions_3qq0n_41{display:flex;justify-content:flex-end;gap:var(--space-3)}._modalSecondary_3qq0n_47{background:transparent;border:1px solid var(--border-primary);color:var(--text-primary);border-radius:var(--radius-md);padding:var(--space-2) var(--space-4);cursor:pointer;font-size:var(--font-size-sm)}._modalPrimary_3qq0n_57{background:var(--accent, var(--color-danger));border:none;color:var(--accent-text, var(--color-danger-text));border-radius:var(--radius-md);padding:var(--space-2) var(--space-4);cursor:pointer;font-size:var(--font-size-sm);font-weight:600}._modalSecondary_3qq0n_47:disabled,._modalPrimary_3qq0n_57:disabled{opacity:.6;cursor:default}._statsGrid_o4nf0_1{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--space-3);margin-bottom:var(--space-4)}._statCard_o4nf0_8{background:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:var(--radius-md);padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-1)}._statLabel_o4nf0_18{font-size:var(--font-size-xs);text-transform:uppercase;letter-spacing:.05em;color:var(--text-tertiary);font-weight:600}._statValue_o4nf0_26{font-size:var(--font-size-xl);font-weight:700;color:var(--text-primary)}._statMeta_o4nf0_32{font-size:var(--font-size-sm);font-weight:500;color:var(--text-primary)}._statusBanner_o4nf0_38{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);font-size:var(--font-size-sm);margin-bottom:var(--space-4);flex-wrap:wrap}._statusSuccess_o4nf0_49{background:color-mix(in srgb,var(--color-success, #22c55e) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-success, #22c55e) 25%,transparent);color:var(--text-primary)}._statusUpdating_o4nf0_55{background:#6366f11a;border:1px solid rgba(99,102,241,.3);color:var(--text-primary)}._statusError_o4nf0_61{background:color-mix(in srgb,var(--color-danger) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-danger) 20%,transparent);color:var(--text-primary)}._sha_o4nf0_67{margin-left:auto;font-family:monospace;font-size:var(--font-size-xs);color:var(--text-tertiary)}._settingItem_o4nf0_74{border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._settingTitle_o4nf0_79{font-weight:600;color:var(--text-primary);font-size:var(--font-size-sm)}._settingSubtitle_o4nf0_85{font-size:var(--font-size-sm);color:var(--text-secondary);margin-top:var(--space-1);line-height:1.5}._actionsRow_o4nf0_92{margin-top:var(--space-6);display:flex;gap:var(--space-3)}._status_1wbo0_1{margin-top:var(--space-4);font-size:var(--font-size-sm);color:var(--text-primary)}._warningText_1wbo0_7{margin:0 0 var(--space-4)!important}._ackLabel_1wbo0_11{display:flex;align-items:flex-start;gap:var(--space-2);font-size:var(--font-size-sm);color:var(--text-primary);cursor:pointer}._ackLabel_1wbo0_11 input{margin-top:2px}._settingItem_68mz3_1{border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._field_68mz3_6{display:flex;flex-direction:column;gap:.5rem;margin-bottom:var(--space-4)}._field_68mz3_6 label{font-size:.9rem;color:var(--text-secondary);font-weight:500}._input_68mz3_19{background:var(--bg-secondary);border:1px solid var(--border-primary);color:var(--text-primary);padding:.6rem;border-radius:4px;width:100%;max-width:400px}._input_68mz3_19:hover{border-color:var(--border-secondary)}._input_68mz3_19:focus{outline:none;border-color:var(--accent);box-shadow:var(--shadow-input-focus)}._actions_68mz3_39{display:flex;gap:var(--space-3);flex-wrap:wrap}._status_68mz3_45{margin-top:var(--space-4);padding:var(--space-3) var(--space-4);background:color-mix(in srgb,var(--accent) 10%,transparent);border-radius:var(--radius-md);color:var(--accent-light);font-size:var(--font-size-sm);font-weight:500}.alert{display:flex;align-items:flex-start;gap:var(--space-3);padding:var(--space-4);border-radius:var(--radius-md);font-size:var(--font-size-sm);border:1px solid transparent}.alert-info{background:color-mix(in srgb,var(--accent) 10%,transparent);border-color:var(--accent);color:var(--text-primary)}.alert-success{background:color-mix(in srgb,var(--color-success) 10%,transparent);border-color:var(--color-success);color:var(--color-success)}.alert-warning{background:color-mix(in srgb,var(--color-warning) 10%,transparent);border-color:var(--color-warning);color:var(--color-warning)}.alert-error{background:color-mix(in srgb,var(--color-danger) 10%,transparent);border-color:var(--color-danger);color:var(--color-danger)}
@@ -0,0 +1,21 @@
1
+ import{d as s,u as e,S as ge,A as Z,h as G,q as me,T as Me,p as qe,g as we,_ as ze}from"./vendor-core-DfaOB3Rn.js";import{b as pe,u as te}from"./vendor-query-BBT5_sHx.js";import{N as ee,O as J,P as U,Q as be,B as S,R as Ue,L as K,d as Ke,H as _e,t as C,n as Te,l as Ee,F as Ce,S as X,q as H,U as ke,V as Fe,W as $e,u as He,e as We,X as Be,G as le,p as je,Y as Qe,Z as Ve}from"./index-fS4AGBy2.js";import{I as B}from"./vendor-icons-DrybRNxP.js";import{T as $}from"./ToggleSwitch-CN_ppEc9.js";import{M as Ye}from"./MatureConsentModal-J7mF0tSH.js";const Je="_sectionCard_1vuib_1",Xe="_dangerCard_1vuib_20",Ze="_settingRow_1vuib_31",L={sectionCard:Je,dangerCard:Xe,settingRow:Ze};function et(){const{data:t}=pe(ee),{data:o}=pe({queryKey:["profiles"],queryFn:()=>J("/api/profiles/status"),enabled:!!t?.owner}),c=te(),[g,p]=s(null),[h,k]=s(""),[y,i]=s(""),[r,m]=s(""),[f,d]=s(""),[P,l]=s(""),[v,_]=s(!1),[T,O]=s(null),I=async a=>{_(!0),l("");try{await J("/api/profiles/update",{method:"POST",body:JSON.stringify(a)}),await c.invalidateQueries({queryKey:ee.queryKey}),k(""),i(""),l("Profile saved")}catch(N){l(N.message)}finally{_(!1)}};return t?e("section",{className:L.sectionCard,children:[e("h3",{children:"Your profile"}),e("p",{children:"Keep using this profile, rename it, or add another person with their own library and connections."}),e("div",{className:U.avatarRow,children:[e(be,{image:t.image,name:t.name}),e("label",{className:U.uploadButton,children:[e(B,{name:"upload"}),e("span",{children:"Upload image"}),e("input",{className:U.fileInput,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",disabled:v,onChange:async a=>{const N=a.currentTarget.files?.[0];if(a.currentTarget.value="",!N)return;if(N.size>2*1024*1024){l("Image must be smaller than 2 MB");return}const R=new FileReader;R.onerror=()=>l("Could not read image"),R.onload=()=>{I({avatar:R.result})},R.readAsDataURL(N)}})]}),t.avatar&&e(S,{variant:"secondary",disabled:v,onClick:()=>I({avatar:null}),children:"Clear uploaded image"})]}),e("p",{children:"Your uploaded image takes priority, followed by your active cloud account image, then the default user icon."}),e("form",{className:U.form,onSubmit:a=>{a.preventDefault(),I({name:g??t.name})},children:[e("label",{className:U.field,children:["Profile name",e("input",{value:g??t.name,maxLength:60,required:!0,onChange:a=>p(a.currentTarget.value)})]}),e(S,{type:"submit",disabled:v,children:"Save name"})]}),e("form",{className:U.form,onSubmit:a=>{a.preventDefault(),I({password:h,currentPassword:y})},children:[t.protected&&e("label",{className:U.field,children:["Current password",e("input",{type:"password",autoComplete:"current-password",value:y,required:!0,maxLength:256,onChange:a=>i(a.currentTarget.value)})]}),e("label",{className:U.field,children:[t.protected?"New password (empty removes protection)":"Protect this profile",e("input",{type:"password",autoComplete:"new-password",value:h,minLength:8,maxLength:256,onChange:a=>k(a.currentTarget.value)})]}),e(S,{type:"submit",disabled:v,children:"Save password"})]}),e(S,{variant:"secondary",disabled:v,onClick:async()=>{_(!0);try{await J("/api/profiles/logout",{method:"POST"}),Ue()}catch(a){l(a.message),_(!1)}},children:"Switch profile / sign out"}),t.owner&&e("form",{className:U.form,onSubmit:async a=>{a.preventDefault(),_(!0),l("");try{await J("/api/profiles/create",{method:"POST",body:JSON.stringify({name:r,password:f})}),m(""),d(""),await c.invalidateQueries({queryKey:["profiles"]}),l("Profile created. Sign out to switch to it.")}catch(N){l(N.message)}finally{_(!1)}},children:[e("h3",{children:"Add another profile"}),e("p",{children:"Protect your owner profile first. New profiles start empty and do not inherit your accounts. A profile without a password is accessible to anyone who passes the LAN lock."}),e("label",{className:U.field,children:["Name",e("input",{required:!0,maxLength:60,value:r,onChange:a=>m(a.currentTarget.value)})]}),e("label",{className:U.field,children:["Password (optional)",e("input",{type:"password",autoComplete:"new-password",minLength:8,maxLength:256,value:f,onChange:a=>d(a.currentTarget.value)})]}),e(S,{type:"submit",disabled:v||!t.protected,children:"Create profile"})]}),t.owner&&o?.profiles.some(a=>!a.owner)&&e(ge,{children:[e("h3",{children:"Other profiles"}),e("ul",{className:U.profileList,children:o.profiles.filter(a=>!a.owner).map(a=>e("li",{children:[e("span",{className:U.smallAvatar,children:e(be,{image:a.avatar??a.cloudAvatar,name:a.name})}),e("span",{className:U.profileName,children:a.name}),e(S,{variant:"danger",size:"sm",disabled:v,onClick:()=>{l(""),O(a)},children:"Delete"})]},a.id))})]}),e(K,{isOpen:!!T,onClose:v?void 0:()=>O(null),title:"Delete profile?",width:"sm",footer:e(ge,{children:[e(S,{variant:"secondary",disabled:v,onClick:()=>O(null),children:"Cancel"}),e(S,{variant:"danger",loading:v,onClick:async()=>{if(T){_(!0);try{await J("/api/profiles/delete",{method:"POST",body:JSON.stringify({id:T.id,confirm:!0})}),await c.invalidateQueries({queryKey:["profiles"]}),O(null),l("Profile deleted. Local files will be removed when Dango restarts.")}catch(a){l(a.message),O(null)}finally{_(!1)}}},children:"Delete profile"})]}),children:[e("p",{children:["Delete ",e("strong",{children:T?.name}),"? This signs them out immediately. Their local libraries, settings and connections will be removed when Dango next restarts."]}),e("p",{children:"Cloud backups and tracker lists will stay intact. Export any library you want to keep before deleting."})]}),P&&e("p",{role:"status",children:P})]}):null}const ce={"title-preference-container":"_title-preference-container_sdqgs_1","toggle-button":"_toggle-button_sdqgs_21","toggle-label":"_toggle-label_sdqgs_51"},de=["name","nativeName","englishName"],ue={name:"Default (Romaji)",nativeName:"Native",englishName:"English"},tt=()=>{const{titlePreference:t,setTitlePreference:o,loading:c}=Ke(),g=_e(),[p,h]=s(ue[t]),[k,y]=s(!1),i=Z(null);G(()=>{c||h(ue[t])},[t,c]);const r=async()=>{if(k)return;y(!0);const f=(de.indexOf(t)+1)%de.length,d=de[f],P=ue[d];i.current&&(i.current.style.transform="translateX(-100%)",i.current.style.opacity="0"),setTimeout(async()=>{h(P),o(d),i.current&&(i.current.style.transition="none",i.current.style.transform="translateX(100%)",i.current.style.opacity="0",i.current.offsetWidth,i.current.style.transition="transform 0.3s ease-out, opacity 0.3s ease-out",i.current.style.transform="translateX(0)",i.current.style.opacity="1");try{await g.mutateAsync({key:"titlePreference",value:d})}catch(l){console.error("Error saving title preference:",l)}finally{y(!1)}},300)};return c?e("p",{children:"Loading title preference..."}):e("div",{className:ce["title-preference-container"],children:[e("h4",{children:"Anime Title Display Preference"}),e("button",{onClick:r,className:ce["toggle-button"],disabled:k,children:e("span",{ref:i,className:ce["toggle-label"],children:p})})]})},at="_settingsHeader_gfwoa_1",nt="_pageTitle_gfwoa_6",rt="_pageSubtitle_gfwoa_14",st="_settingsLayout_gfwoa_20",it="_sidebar_gfwoa_27",ot="_sidebarIndicator_gfwoa_35",lt="_sidebarItem_gfwoa_50",ct="_active_gfwoa_72",dt="_mainContent_gfwoa_80",ut="_tabContent_gfwoa_85",ht="_settingItem_gfwoa_103",gt="_shortcutContainer_gfwoa_108",mt="_shortcutGroup_gfwoa_115",pt="_shortcutGroupTitle_gfwoa_121",ft="_shortcutGrid_gfwoa_130",yt="_shortcutCard_gfwoa_136",vt="_controls_gfwoa_170",wt="_status_gfwoa_176",u={settingsHeader:at,pageTitle:nt,pageSubtitle:rt,settingsLayout:st,sidebar:it,sidebarIndicator:ot,sidebarItem:lt,active:ct,mainContent:dt,tabContent:ut,settingItem:ht,shortcutContainer:gt,shortcutGroup:mt,shortcutGroupTitle:pt,shortcutGrid:ft,shortcutCard:yt,controls:vt,status:wt},bt="_title_tm30b_11",Ct="_signIn_tm30b_18",kt="_userInfo_tm30b_25",St="_warning_tm30b_47",Nt="_formGroup_tm30b_54",_t="_label_tm30b_58",Tt="_inputWrapper_tm30b_68",Lt="_input_tm30b_68",Pt="_select_tm30b_92",It="_actions_tm30b_109",xt="_hr_tm30b_117",w={title:bt,signIn:Ct,userInfo:kt,warning:St,formGroup:Nt,label:_t,inputWrapper:Tt,input:Lt,select:Pt,actions:It,hr:xt},Rt=()=>{const t=te(),[o,c]=s(!0),[g,p]=s(!1),[h,k]=s(!1),[y,i]=s(null),[r,m]=s({status:"idle"}),[f,d]=s(!1),[P,l]=s(""),[v,_]=s(!1),T=Z(null),[O,I]=s({show:!1,message:"",type:"info"}),a=()=>{T.current&&(window.clearInterval(T.current),T.current=null)},N=me(b=>{k(b.authenticated),i(b.user||b.device.user||null),m(b.device),d(!!b.hasCustomClientId)},[]),R=me(async()=>{const b=await C.auth.githubStatus.query();N(b)},[N]),q=async()=>{try{const b=await C.auth.githubPoll.query();m(b),b.status==="success"?(a(),await t.invalidateQueries({queryKey:ee.queryKey}),await R(),I({show:!0,message:"GitHub authentication complete. Sync has been initialized.",type:"success"})):b.status==="error"&&(a(),I({show:!0,message:b.error||"GitHub authentication failed.",type:"error"}))}catch{a(),I({show:!0,message:"Failed to poll GitHub authentication status.",type:"error"})}},x=(b=5)=>{a(),T.current=window.setInterval(q,Math.max(b,5)*1e3)};G(()=>(R().catch(()=>{I({show:!0,message:"Failed to load GitHub sync status.",type:"error"})}).finally(()=>c(!1)),a),[R]);const A=async()=>{p(!0);try{const b=await C.auth.githubStart.mutate();m(b),x(b.verification?.interval)}catch(b){I({show:!0,message:b instanceof Error?b.message:"Failed to start GitHub authentication.",type:"error"})}finally{p(!1)}},M=async()=>{try{await C.auth.githubLogout.mutate(),await t.invalidateQueries({queryKey:ee.queryKey}),k(!1),i(null),m({status:"idle"}),I({show:!0,message:"Signed out of GitHub sync.",type:"success"})}catch{I({show:!0,message:"Failed to sign out of GitHub.",type:"error"})}},j=async()=>{_(!0);try{await C.auth.saveGithubAuth.mutate({clientId:P}),l(""),await R(),I({show:!0,message:"Custom GitHub auth saved.",type:"success"})}catch{I({show:!0,message:"Failed to save override.",type:"error"})}finally{_(!1)}},Q=async()=>{_(!0);try{await C.auth.saveGithubAuth.mutate({clientId:""}),l(""),await R(),I({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{I({show:!0,message:"Failed to clear override.",type:"error"})}finally{_(!1)}};return o?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:L.sectionCard,children:[e("h3",{className:w.title,children:"GitHub Cloud Sync"}),e("p",{className:w.signIn,children:"Sync local data through a private GitHub repository named dango-sync-data."}),h&&y?e("div",{className:w.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:y.name||y.login})]}),e(S,{variant:"danger",onClick:M,children:"Sign Out"})]}):e("div",{className:w.signIn,children:e(S,{onClick:A,disabled:g||r.status==="pending",children:g||r.status==="pending"?"Waiting for GitHub...":"Sign in with GitHub"})}),r.status==="pending"&&r.verification&&e(ge,{children:[e("hr",{className:w.hr}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Verification URL"}),e("div",{className:w.inputWrapper,children:[e("input",{className:w.input,value:r.verification.verification_uri,readOnly:!0}),e(S,{onClick:()=>{const b=r.verification?.verification_uri;b&&/^https?:\/\//i.test(b)&&window.open(b,"_blank","noopener,noreferrer")},children:"Open"})]})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Device Code"}),e("input",{className:w.input,value:r.verification.user_code,readOnly:!0})]})]}),r.status==="error"&&e("p",{className:w.warning,children:r.error}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",f?"(override active)":""]}),e("div",{className:w.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:w.label,children:"Client ID (optional)"}),e("input",{className:w.input,value:P,onChange:b=>l(b.currentTarget.value),placeholder:"Your GitHub OAuth app ID"})]}),e("div",{className:w.actions,children:[e(S,{onClick:j,disabled:v,children:"Save override"}),e(S,{variant:"secondary",onClick:Q,disabled:v,children:"Use dango defaults"})]})]}),e(K,{isOpen:O.show,onClose:()=>I(b=>({...b,show:!1})),width:"sm",children:[e(K.Body,{children:e("p",{children:O.message})}),e(K.Actions,{children:e(S,{onClick:()=>I(b=>({...b,show:!1})),children:"OK"})})]})]})},Dt=()=>{const[t,o]=s(!0),[c,g]=s(null),[p,h]=s(!1),[k,y]=s(!1),[i,r]=s(""),[m,f]=s(""),[d,P]=s(""),[l,v]=s(!1),[_,T]=s({show:!1,message:"",type:"info"}),O=async()=>{try{const A=await C.auth.user.query();g(A?.email?A:null)}catch{g(null)}},I=async()=>{try{const[x,A]=await Promise.all([C.auth.configStatus.query(),C.auth.googleAuth.query()]);h(!!x.hasConfig),y(!!(A.hasCustomWorkerUrl||A.hasCustomClientId||A.hasClientSecret))}catch(x){console.error("Failed to fetch config status",x)}};G(()=>{(async()=>{o(!0),await Promise.all([O(),I()]);try{new URLSearchParams(window.location.search).get("google_auth")==="success"&&(await O(),window.history.replaceState(null,"",window.location.pathname))}catch{}o(!1)})();const A=M=>{M.origin===window.location.origin&&typeof M.data=="object"&&M.data!==null&&M.data.type==="GOOGLE_AUTH_SUCCESS"&&(g(M.data.user),window.location.reload())};return window.addEventListener("message",A),()=>window.removeEventListener("message",A)},[]);const a=async()=>{try{const x=await C.auth.googleLogin.mutate();if(x.authenticated){window.location.reload();return}if(x.url){if(typeof window.DangoBridge<"u"){window.location.href=x.url;return}const M=600,j=700,Q=window.innerWidth/2-M/2,b=window.innerHeight/2-j/2;window.open(x.url,"GoogleAuth",`width=${M},height=${j},top=${b},left=${Q}`)}else throw new Error("Auth URL not available")}catch{T({show:!0,message:"Authentication failed. Ensure server is configured correctly.",type:"error"})}},N=async()=>{try{await C.auth.logout.mutate(),g(null),T({show:!0,message:"Successfully signed out.",type:"success"}),window.location.reload()}catch(x){console.error("Sign out failed",x),T({show:!0,message:"Failed to sign out.",type:"error"})}},R=async()=>{v(!0);try{await C.auth.saveGoogleAuth.mutate({workerUrl:i,clientId:m,clientSecret:d}),r(""),f(""),P(""),await I(),T({show:!0,message:"Custom auth saved. Restart may be required.",type:"success"})}catch{T({show:!0,message:"Failed to save override.",type:"error"})}finally{v(!1)}},q=async()=>{v(!0);try{await C.auth.saveGoogleAuth.mutate({workerUrl:"",clientId:"",clientSecret:""}),r(""),f(""),P(""),await I(),T({show:!0,message:"Custom auth cleared. Using dango defaults.",type:"success"})}catch{T({show:!0,message:"Failed to clear override.",type:"error"})}finally{v(!1)}};return t?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:L.sectionCard,children:[e("h3",{className:w.title,children:"Google Drive Sync"}),c?e("div",{className:w.userInfo,children:[e("p",{children:["Signed in as: ",e("strong",{children:c.name})," (",c.email,")"]}),e(S,{variant:"danger",onClick:N,children:"Sign Out"})]}):e("div",{className:w.signIn,children:[e("p",{children:"Sign in with your Google account to enable synchronization features."}),e(S,{onClick:a,disabled:!p,children:"Sign in with Google"}),!p&&e("p",{className:w.warning,children:"Google sync is not configured on the server."})]}),e("details",{style:{marginTop:"1rem",fontSize:"var(--font-size-sm)"},children:[e("summary",{style:{cursor:"pointer",color:"var(--text-secondary)"},children:["Advanced: use your own auth ",k?"(override active)":""]}),e("div",{className:w.formGroup,style:{marginTop:"0.75rem"},children:[e("label",{className:w.label,children:"Worker URL (optional)"}),e("input",{className:w.input,value:i,onChange:x=>r(x.currentTarget.value),placeholder:"https://your-worker.workers.dev"})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Client ID (optional)"}),e("input",{className:w.input,value:m,onChange:x=>f(x.currentTarget.value),placeholder:"Your Google OAuth client ID"})]}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Client Secret (optional)"}),e("input",{type:"password",className:w.input,value:d,onChange:x=>P(x.currentTarget.value),placeholder:"Your Google OAuth secret"})]}),e("div",{className:w.actions,children:[e(S,{onClick:R,disabled:l,children:"Save override"}),e(S,{variant:"secondary",onClick:q,disabled:l,children:"Use dango defaults"})]})]}),e(K,{isOpen:_.show,onClose:()=>T(x=>({...x,show:!1})),width:"sm",children:[e(K.Body,{children:e("p",{children:_.message})}),e(K.Actions,{children:e(S,{onClick:()=>T(x=>({...x,show:!1})),children:"OK"})})]})]})},At="_settingItem_3qq0n_1",Ot="_modalOverlay_3qq0n_6",Gt="_modal_3qq0n_6",Mt="_modalActions_3qq0n_41",qt="_modalSecondary_3qq0n_47",zt="_modalPrimary_3qq0n_57",W={settingItem:At,modalOverlay:Ot,modal:Gt,modalActions:Mt,modalSecondary:qt,modalPrimary:zt},Ut={anime:{heading:"Watchlist Preferences",blurb:"Customize your experience when managing your watchlist and series entries.",skipKey:"skipRemoveConfirmation",ignoreKey:"ignoreAdultContent",listOnlyKey:"cwWatchlistOnly",skipLabel:"Skip confirmation when removing from watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in watchlist",listNoun:"watchlist",continueNoun:"continue watching",adultCountUrl:"/api/continue-watching/adult-count",purgeUrl:"/api/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["allContinueWatching"]]},manga:{heading:"Reading List Preferences",blurb:"Customize your experience when managing your reading list and manga entries.",skipKey:"mangaSkipRemoveConfirmation",ignoreKey:"mangaIgnoreAdultContent",listOnlyKey:"mangaCwWatchlistOnly",skipLabel:"Skip confirmation when removing from reading list",ignoreLabel:"Hide adult content from continue reading",listOnlyLabel:"Only show continue reading for manga in reading list",listNoun:"reading list",continueNoun:"continue reading",adultCountUrl:"/api/manga/continue-reading/adult-count",purgeUrl:"/api/manga/continue-reading/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue reading`,invalidateKeys:[["manga-continue-reading"]]},tv:{heading:"TV Watchlist Preferences",blurb:"Customize your experience when managing your TV watchlist and series entries.",skipKey:"tvSkipRemoveConfirmation",ignoreKey:"tvIgnoreAdultContent",listOnlyKey:"tvCwWatchlistOnly",skipLabel:"Skip confirmation when removing from TV watchlist",ignoreLabel:"Hide adult content from continue watching",listOnlyLabel:"Only show continue watching for shows in TV watchlist",listNoun:"TV watchlist",continueNoun:"continue watching",adultCountUrl:"/api/tv/continue-watching/adult-count",purgeUrl:"/api/tv/continue-watching/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue watching`,invalidateKeys:[["tv-continue-watching"]]},asmr:{heading:"Listening List Preferences",blurb:"Customize your experience when managing your listening list and work entries.",skipKey:"asmrSkipRemoveConfirmation",ignoreKey:"asmrIgnoreAdultContent",listOnlyKey:"asmrCwWatchlistOnly",skipLabel:"Skip confirmation when removing from listening list",ignoreLabel:"Hide adult content from continue listening",listOnlyLabel:"Only show continue listening for works in listening list",listNoun:"listening list",continueNoun:"continue listening",adultCountUrl:"/api/asmr/continue-listening/adult-count",purgeUrl:"/api/asmr/continue-listening/purge-adult",purgeDoneText:t=>`Removed ${t??0} entries from continue listening`,invalidateKeys:[["asmr-continue-listening"]]}},Kt=(t,o)=>{if(t==null)return o;const c=String(t);return c==="true"||c==="1"?!0:c==="false"||c==="0"?!1:o},Se=(t,o,c)=>{const[g,p]=s(o),[h,k]=s(!1),y=te();return G(()=>{(async()=>{try{const m=await C.settings.getByKey.query({key:t});p(Kt(m.value,o))}catch(m){console.error("Failed to fetch setting",m)}})()},[t,o]),{value:g,setValue:p,isUpdating:h,toggle:async()=>{if(h)return;k(!0);const r=!g;p(r);try{await C.settings.set.mutate({key:t,value:r});for(const m of c)y.invalidateQueries({queryKey:m})}catch(m){console.error("Error saving setting:",m),p(!r)}finally{k(!1)}}}},Et=()=>{const{contentType:t}=Te(),o=Ut[t],[c,g]=s(!1),[p,h]=s(!0),[k,y]=s(!1),i=Se(o.ignoreKey,!0,o.invalidateKeys),r=Se(o.listOnlyKey,!1,o.invalidateKeys),[m,f]=s(null),[d,P]=s(!1),l=te(),v=Ee();G(()=>{h(!0),(async()=>{try{const N=await C.settings.getByKey.query({key:o.skipKey});String(N.value)==="true"||String(N.value)==="1"?g(!0):g(!1)}catch(N){console.error("Failed to fetch setting",N)}finally{h(!1)}})()},[o.skipKey]);const _=async()=>{if(k)return;y(!0);const a=!c;g(a);try{await C.settings.set.mutate({key:o.skipKey,value:a})}catch(N){console.error("Error saving setting:",N),g(!a)}finally{y(!1)}},T=async()=>{if(!i.isUpdating){if(i.value)try{let a;if(t==="anime"?a=(await C.continueWatching.adultCount.query()).count:t==="manga"?a=(await C.mangaProgress.adultCount.query()).count:t==="asmr"?a=(await C.asmrProgress.adultCount.query()).count:a=(await C.tvProgress.adultCount.query()).count,typeof a=="number"&&a>0){f(a);return}}catch(a){console.error("Failed to fetch adult count",a)}i.toggle()}},O=()=>{f(null),i.toggle()},I=async()=>{if(!d){P(!0);try{let a;t==="anime"?a=(await C.continueWatching.purgeAdult.mutate()).removed:t==="manga"?a=(await C.mangaProgress.purgeAdult.mutate()).removed:t==="asmr"?a=(await C.asmrProgress.purgeAdult.mutate()).removed:a=(await C.tvProgress.purgeAdult.mutate()).removed,Ce.success(o.purgeDoneText(a??0));for(const N of o.invalidateKeys)l.invalidateQueries({queryKey:N});t==="anime"&&l.invalidateQueries(v.continueWatching.pathFilter()),t==="manga"&&l.invalidateQueries(v.mangaProgress.pathFilter()),t==="asmr"&&l.invalidateQueries(v.asmrProgress.pathFilter()),t==="tv"&&l.invalidateQueries(v.tvProgress.pathFilter())}catch(a){console.error("Failed to purge adult entries",a),Ce.error("Failed to remove adult entries")}finally{P(!1),f(null)}i.toggle()}};return p?e("div",{children:"Loading settings..."}):e("div",{className:L.sectionCard,children:[e("h3",{children:o.heading}),e("p",{children:o.blurb}),e("div",{className:W.settingItem,children:e("div",{className:L.settingRow,children:[e("label",{htmlFor:"skip-confirmation-toggle",children:o.skipLabel}),e($,{isChecked:c,onChange:_,id:"skip-confirmation-toggle",disabled:k})]})}),e("div",{className:W.settingItem,children:e("div",{className:L.settingRow,children:[e("label",{htmlFor:"ignore-adult-toggle",children:o.ignoreLabel}),e($,{isChecked:i.value,onChange:T,id:"ignore-adult-toggle",disabled:i.isUpdating})]})}),e("div",{className:W.settingItem,children:e("div",{className:L.settingRow,children:[e("label",{htmlFor:"cw-watchlist-only-toggle",children:o.listOnlyLabel}),e($,{isChecked:r.value,onChange:r.toggle,id:"cw-watchlist-only-toggle",disabled:r.isUpdating})]})}),m!==null&&e("div",{className:W.modalOverlay,onClick:()=>f(null),children:e("div",{className:W.modal,onClick:a=>a.stopPropagation(),children:[e("h4",{children:"Show adult entries?"}),e("p",{children:[m," adult ",m===1?"entry":"entries"," not in your"," ",o.listNoun," ",m===1?"is":"are"," currently hidden from"," ",o.continueNoun,". You can purge ",m===1?"it":"them"," from the database instead of showing ",m===1?"it":"them","."]}),e("div",{className:W.modalActions,children:[e("button",{type:"button",className:W.modalSecondary,onClick:O,disabled:d,children:"Show them"}),e("button",{type:"button",className:W.modalPrimary,onClick:I,disabled:d,children:d?"Purging...":`Purge ${m}`})]})]})})]})},Ft="_statsGrid_o4nf0_1",$t="_statCard_o4nf0_8",Ht="_statLabel_o4nf0_18",Wt="_statValue_o4nf0_26",Bt="_statMeta_o4nf0_32",jt="_statusBanner_o4nf0_38",Qt="_statusSuccess_o4nf0_49",Vt="_statusUpdating_o4nf0_55",Yt="_statusError_o4nf0_61",Jt="_sha_o4nf0_67",Xt="_settingItem_o4nf0_74",Zt="_settingTitle_o4nf0_79",ea="_settingSubtitle_o4nf0_85",ta="_actionsRow_o4nf0_92",D={statsGrid:Ft,statCard:$t,statLabel:Ht,statValue:Wt,statMeta:Bt,statusBanner:jt,statusSuccess:Qt,statusUpdating:Vt,statusError:Yt,sha:Jt,settingItem:Xt,settingTitle:Zt,settingSubtitle:ea,actionsRow:ta},aa=()=>{const[t,o]=s(null),[c,g]=s(!0),[p,h]=s(!1),[k,y]=s(!1),i=Z(null),r=async()=>{try{const l=await C.settings.offlineDbInfo.query();return o(l),l}catch(l){console.error("Failed to fetch offline DB info:",l)}finally{g(!1)}return null};G(()=>(r(),()=>{i.current&&window.clearInterval(i.current)}),[]),G(()=>{t?.isRefreshing?i.current||(i.current=window.setInterval(async()=>{const l=await r();l&&!l.isRefreshing&&i.current&&(window.clearInterval(i.current),i.current=null)},2e3)):i.current&&(window.clearInterval(i.current),i.current=null)},[t?.isRefreshing]);const m=async()=>{if(!t||p)return;const l=!t.autoUpdateEnabled;h(!0),o({...t,autoUpdateEnabled:l});try{await C.settings.setOfflineDbAutoUpdate.mutate({enabled:l})}catch(v){console.error("Failed to update auto update setting:",v),o({...t,autoUpdateEnabled:!l})}finally{h(!1)}},f=async()=>{if(!(t?.isRefreshing||k)){y(!0);try{await C.settings.triggerOfflineDbUpdate.mutate(),o(l=>l?{...l,isRefreshing:!0,lastStatus:"updating",lastMessage:"Downloading database..."}:null)}catch(l){console.error("Failed to trigger offline DB update:",l)}finally{y(!1)}}},d=l=>{if(!l)return"Never";try{return new Date(l).toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"})}catch{return l}},P=t?.isRefreshing||k;return e("div",{className:L.sectionCard,children:[e("h3",{children:"Offline Metadata Database"}),e("p",{children:"Local MAL to AniList ID map used for instant imports and metadata enrichment without hitting rate-limited APIs. Updates automatically every Saturday in the background."}),e("div",{className:D.statsGrid,children:[e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"MAL Mapped"}),e("span",{className:D.statValue,children:c?"-":(t?.totalMalMapped??0).toLocaleString()})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Release"}),e("span",{className:D.statMeta,children:c?"-":t?.releaseTag??"Never"})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Last Checked"}),e("span",{className:D.statMeta,children:c?"-":d(t?.lastCheckedAt??null)})]}),e("div",{className:D.statCard,children:[e("span",{className:D.statLabel,children:"Last Updated"}),e("span",{className:D.statMeta,children:c?"-":d(t?.lastUpdatedAt??null)})]})]}),t?.lastMessage&&e("div",{className:`${D.statusBanner} ${t.lastStatus==="failed"?D.statusError:t.lastStatus==="updating"?D.statusUpdating:D.statusSuccess}`,children:[e("span",{children:t.lastMessage}),t.contentSha256&&e("span",{className:D.sha,children:["sha:",t.contentSha256.slice(0,12)]})]}),e("div",{className:D.settingItem,children:e("div",{className:L.settingRow,children:[e("div",{children:[e("span",{className:D.settingTitle,children:"Weekly Automatic Updates (Saturdays)"}),e("div",{className:D.settingSubtitle,children:"Download and index new database releases in the background. Catches up on startup if the server was offline."})]}),e($,{id:"offline-db-auto-update-toggle",isChecked:t?t.autoUpdateEnabled:!0,onChange:m,disabled:c||p})]})}),e("div",{className:D.actionsRow,children:e(S,{onClick:f,disabled:c||P,children:P?"Updating Database...":"Update Offline Database Now"})})]})},na="_status_1wbo0_1",ra="_warningText_1wbo0_7",sa="_ackLabel_1wbo0_11",he={status:na,warningText:ra,ackLabel:sa},ia=()=>{const t=te(),[o,c]=s(!1),[g,p]=s(!1),[h,k]=s(!1),[y,i]=s(""),r=()=>{p(!1),i(""),c(!0)},m=()=>{h||(c(!1),p(!1))},f=async()=>{if(!(!g||h)){k(!0),i("");try{const d=await X("/api/database/clear",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({confirm:!0})}),P=await d.json();if(!d.ok)throw new Error(P.error||"Failed to clear database");const l=P.deleted,v=P.deletedManga,_=P.deletedTv,T=P.deletedAsmr,O=Object.values(l).reduce((R,q)=>R+(q||0),0)+Object.values(v??{}).reduce((R,q)=>R+(q||0),0)+Object.values(_??{}).reduce((R,q)=>R+(q||0),0)+Object.values(T??{}).reduce((R,q)=>R+(q||0),0),I=(v?.manga_library??0)+(v?.manga_progress??0),a=(_?.tv_library??0)+(_?.tv_progress??0),N=(T?.asmr_library??0)+(T?.asmr_progress??0);i(`Library cleared - ${l.watchlist??0} watchlist entries, ${I} manga rows, ${a} TV rows, ${N} ASMR rows and ${O} total rows removed.`),t.invalidateQueries({queryKey:[H.watchlist]}),t.invalidateQueries({queryKey:[H.continueWatching]}),t.invalidateQueries({queryKey:[H.mangaLibrary]}),t.invalidateQueries({queryKey:[H.mangaContinueReading]}),t.invalidateQueries({queryKey:[H.tvLibrary]}),t.invalidateQueries({queryKey:[H.tvContinueWatching]}),t.invalidateQueries({queryKey:[H.asmrLibrary]}),t.invalidateQueries({queryKey:[H.asmrContinueListening]}),c(!1)}catch(d){i(d.message)}finally{k(!1),p(!1)}}};return e("div",{className:`${L.sectionCard} ${L.dangerCard}`,children:[e("h3",{children:"Danger Zone"}),e("p",{children:"Permanently delete your library (watchlist, watched episodes, queue, cached show metadata, manga reading list and reading progress, TV watchlist and watch progress, ASMR listening list and listening progress) to start fresh. Your settings, sync state and the offline metadata cache are preserved."}),e(S,{variant:"danger",onClick:r,children:"Clear Library Data"}),y&&e("p",{className:he.status,children:y}),e(K,{isOpen:o,onClose:m,title:"Clear library data?",width:"sm",children:[e(K.Body,{children:[e("p",{className:he.warningText,children:"This permanently deletes everything in your library. It acts on the active database (dev or prod, per server config) and cannot be undone. Settings, sync state and the offline metadata cache are kept."}),e("label",{className:he.ackLabel,children:[e("input",{type:"checkbox",checked:g,onChange:d=>p(d.currentTarget.checked),disabled:h}),e("span",{children:"I understand this permanently deletes my library"})]})]}),e(K.Actions,{children:[e(S,{variant:"secondary",onClick:m,disabled:h,children:"Cancel"}),e(S,{variant:"danger",onClick:f,disabled:!g||h,children:h?"Clearing...":"Yes, delete everything"})]})]})]})},oa=()=>{const[t,o]=s(""),[c,g]=s([]),[p,h]=s(null),[k,y]=s(!0),[i,r]=s({show:!1,message:"",type:"info"}),m=async()=>{try{y(!0);const d=await C.auth.rcloneSettings.query();o(d.remote||""),g(d.availableRemotes||[]),h(d.activeRemote||null)}catch(d){console.error("Failed to fetch Rclone settings",d)}finally{y(!1)}};G(()=>{m()},[]);const f=async()=>{try{await C.auth.saveRclone.mutate({remote:t}),r({show:!0,message:"Rclone configuration saved successfully. You must restart the server for these changes to take effect.",type:"success"}),m()}catch{r({show:!0,message:"Failed to save Rclone configuration.",type:"error"})}};return k?e("div",{style:{color:"var(--text-secondary)",padding:"1.5rem"},children:"Loading..."}):e("div",{className:L.sectionCard,children:[e("h3",{className:w.title,children:"Rclone Cloud Sync"}),e("p",{className:w.signIn,children:"Configure which Rclone remote to use for database synchronization."}),p?e("div",{className:w.userInfo,children:e("p",{children:["Current Active Remote: ",e("strong",{children:p})]})}):e("p",{className:w.warning,style:{marginBottom:"1.5rem"},children:"Rclone sync is not currently active. Ensure rclone is installed and a remote is configured."}),e("div",{className:w.formGroup,children:[e("label",{className:w.label,children:"Remote Name"}),e("div",{className:w.inputWrapper,children:e("select",{className:w.select,value:t,onChange:d=>o(d.currentTarget.value),children:[e("option",{value:"",children:"(Disabled / None)"}),c.map(d=>e("option",{value:d,children:d},d)),t&&!c.includes(t)&&e("option",{value:t,children:[t," (Manual)"]})]})}),e("p",{className:w.warning,style:{marginTop:"12px"},children:[e("strong",{children:"Note:"})," You can choose which provider is active using the selector at the top of the page."]})]}),e("div",{className:w.actions,children:e(S,{onClick:f,children:"Save Rclone Settings"})}),e(K,{isOpen:i.show,onClose:()=>r(d=>({...d,show:!1})),width:"sm",children:[e(K.Body,{children:e("p",{children:i.message})}),e(K.Actions,{children:e(S,{onClick:()=>r(d=>({...d,show:!1})),children:"OK"})})]})]})},la=()=>{const t=te(),[o,c]=s(null),[g,p]=s(!0),h=async()=>{try{const r=await C.auth.syncSettings.query();c(r)}catch(r){console.error("Failed to fetch sync settings",r)}finally{p(!1)}};G(()=>{h()},[]);const k=async r=>{const m=r.currentTarget.value;try{const f=await C.auth.saveSyncProvider.mutate({provider:m});c(d=>d?{...d,activeProvider:f.activeProvider}:null),await h(),await t.invalidateQueries({queryKey:ee.queryKey}),ke.success(`Sync provider updated to ${m==="default"?"Default Order":m}`)}catch{ke.error("Failed to update sync provider")}};if(g||!o)return null;const y=[{value:"default",label:"Default (Priority Based)"}];o.authenticatedProviders.github&&y.push({value:"github",label:"GitHub"}),o.authenticatedProviders.google&&y.push({value:"google",label:"Google Drive"}),o.authenticatedProviders.rclone&&y.push({value:"rclone",label:"Rclone"}),y.push({value:"none",label:"None (Local Only)"});const i=r=>r==="none"?"Local Only (No Sync)":r==="google"?"Google Drive":r==="github"?"GitHub":r==="rclone"?"Rclone":r;return e("div",{className:L.sectionCard,children:[e("h3",{children:"Active Sync Provider"}),e("p",{children:'Choose which provider to use for synchronization. "Default" uses the first available provider you are logged into.'}),e("div",{style:{marginBottom:"1.5rem",padding:"0.75rem",background:"rgba(255, 255, 255, 0.03)",borderRadius:"var(--radius-md)",borderLeft:"4px solid var(--accent)",fontSize:"var(--font-size-sm)"},children:["Current Status:"," ",e("strong",{style:{color:"var(--accent-light)",textTransform:"capitalize"},children:i(o.actualActiveProvider)})]}),e("div",{className:L.settingRow,children:[e("label",{htmlFor:"sync-provider-select",children:"Selected Preference"}),e("select",{id:"sync-provider-select",value:o.activeProvider,onChange:k,style:{padding:"0.5rem",borderRadius:"var(--radius-md)",background:"rgba(255, 255, 255, 0.05)",color:"var(--text-primary)",border:"1px solid var(--glass-border)",fontSize:"var(--font-size-sm)",minWidth:"220px",outline:"none",cursor:"pointer"},children:y.map(r=>e("option",{value:r.value,children:r.label},r.value))})]})]})};function ca(){return"javascript:"+encodeURIComponent(`(function(){
2
+ if(!/(^|\\.)discord\\.com$/.test(location.hostname)){alert('Dango: use this bookmarklet while on discord.com');return}
3
+ var t=null;
4
+ try{
5
+ window.webpackChunkdiscord_app.push([[Symbol()],{},function(req){
6
+ if(!req.c)return;
7
+ var ms=Object.values(req.c);
8
+ for(var i=0;i<ms.length;i++){var m=ms[i];
9
+ try{
10
+ if(!m.exports||m.exports===window)continue;
11
+ if(typeof m.exports.getToken==='function'){var x=m.exports.getToken();if(x){t=x;return}}
12
+ for(var k in m.exports){try{var ex=m.exports[k];if(ex&&typeof ex.getToken==='function'&&ex[Symbol.toStringTag]!=='IntlMessagesProxy'){var y=ex.getToken();if(y){t=y;return}}}catch(e1){}}
13
+ }catch(e2){}}
14
+ }]);
15
+ window.webpackChunkdiscord_app.pop();
16
+ }catch(e3){}
17
+ if(!t){alert('Dango: could not grab your token. Make sure you are logged in to Discord in this tab, then run the bookmarklet again.');return}
18
+ function copyFallback(){var a=document.createElement('textarea');a.value=t;a.style.position='fixed';a.style.opacity='0';document.body.appendChild(a);a.select();try{document.execCommand('copy')}catch(e4){}document.body.removeChild(a)}
19
+ var done=function(){window.close();setTimeout(function(){if(!window.closed){alert('Dango: token copied to clipboard! Could not close this tab, so just close it, go back to Dango Settings, paste the token and press Save.')}},250)};
20
+ if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t).then(done,function(){copyFallback();done()})}else{copyFallback();done()}
21
+ })()`)}const da=()=>{const t=Me(ca,[]);return e("div",{style:{marginTop:"0.9rem",paddingTop:"0.9rem",borderTop:"1px dashed var(--border-color)"},children:[e("h4",{style:{margin:"0 0 0.35rem",fontSize:"0.95rem"},children:"Grab the token automatically (bookmarklet)"}),e("p",{style:{margin:"0 0 0.6rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Set this up once and you never have to dig through DevTools: the bookmarklet copies your Discord token to the clipboard and closes the Discord tab - then you just paste it above and press Save."}),e("ol",{style:{margin:"0 0 0.75rem",paddingLeft:"1.25rem",fontSize:"0.85rem",color:"var(--text-secondary)",display:"grid",gap:"0.3rem"},children:[e("li",{children:["Drag the ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," ","button below onto your bookmarks bar (press ",e("kbd",{children:"Ctrl"}),"+",e("kbd",{children:"Shift"}),"+",e("kbd",{children:"B"})," ","first if the bar is hidden)."]}),e("li",{children:["Click ",e("strong",{style:{color:"var(--text-primary)"},children:"Open Discord"})," and log in (skip this if you are already logged in)."]}),e("li",{children:["On the Discord tab, click the"," ",e("strong",{style:{color:"var(--text-primary)"},children:"Dango Token Grabber"})," bookmark. The token lands in your clipboard and the tab closes on its own - come back here, paste it above and press ",e("strong",{children:"Save"}),"."]})]}),e("div",{style:{display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("a",{href:t,onClick:g=>{g.preventDefault(),alert("Drag this button onto your bookmarks bar instead of clicking it, then click it while you are on discord.com.")},title:"Drag me to your bookmarks bar",draggable:!0,style:{display:"inline-flex",alignItems:"center",padding:"0.4rem 0.8rem",borderRadius:"999px",border:"1px dashed var(--accent)",background:"var(--bg-secondary)",color:"var(--text-primary)",fontSize:"0.85rem",textDecoration:"none",cursor:"grab",userSelect:"none"},children:[e(B,{name:"bookmark",style:{marginRight:"0.45rem",color:"var(--accent)"}}),"Dango Token Grabber"]}),e("a",{className:"btn btn-secondary btn-sm",href:"https://discord.com/channels/@me",target:"_blank",rel:"noopener noreferrer",children:"Open Discord"}),e(S,{variant:"ghost",size:"sm",onClick:async()=>{try{await navigator.clipboard.writeText(t),alert('Bookmarklet code copied. Create a new bookmark on your bookmarks bar, name it "Dango Token" and paste the code as its URL.')}catch{alert(`Could not copy automatically. Right-click the "Dango Token Grabber" button and choose "Copy link address" instead, then paste that into a new bookmark's URL.`)}},children:"Copy code"})]}),e("p",{style:{margin:"0.5rem 0 0",fontSize:"0.75rem",color:"var(--text-tertiary)"},children:`"Copy code" is a fallback for browsers that won't drag bookmarklets: create any bookmark, then paste the copied code as its URL.`})]})},ua="_settingItem_68mz3_1",ha="_field_68mz3_6",ga="_input_68mz3_19",ma="_actions_68mz3_39",pa="_status_68mz3_45",E={settingItem:ua,field:ha,input:ga,actions:ma,status:pa},fa=()=>{const[t,o]=s(!1),[c,g]=s(""),[p,h]=s(""),[k,y]=s(!0),[i,r]=s(!1),[m,f]=s("");G(()=>{(async()=>{try{const T=await(await X("/api/auth/app-status")).json();o(T.hasPassword)}catch{console.error("Failed to fetch LAN auth status")}finally{y(!1)}})()},[]);const d=async()=>{if(f(""),c!==p){f("Passwords do not match");return}if(c.length<4){f("Password must be at least 4 characters");return}r(!0);try{const v=await X("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:c})}),_=await v.json();if(!v.ok){f(_.error||"Failed to update password");return}o(_.hasPassword),g(""),h(""),f(_.hasPassword?"Password set successfully":"Password removed")}catch{f("Network error")}finally{r(!1)}},P=async()=>{r(!0);try{const v=await X("/api/auth/app-setup",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:""})}),_=await v.json();if(!v.ok){f(_.error||"Failed to remove password");return}o(!1),g(""),h(""),f("Password removed")}catch{f("Network error")}finally{r(!1)}},l=async()=>{r(!0);try{await X("/api/auth/app-logout",{method:"POST"}),f("Logged out"),window.location.reload()}catch{f("Logout failed")}finally{r(!1)}};return k?e("div",{className:L.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:L.sectionCard,children:[e("h3",{children:"LAN Lock"}),e("p",{children:"Require a password to access this instance from any device, including this one. Sessions persist across server restarts until logout or password change."}),e("div",{className:E.settingItem,children:[e("div",{className:E.field,children:[e("label",{htmlFor:"lan-password",children:"New Password"}),e("input",{id:"lan-password",type:"password",value:c,onChange:v=>g(v.currentTarget.value),placeholder:t?"Leave empty to keep current password":"Enter a password...",className:E.input})]}),e("div",{className:E.field,children:[e("label",{htmlFor:"lan-confirm-password",children:"Confirm Password"}),e("input",{id:"lan-confirm-password",type:"password",value:p,onChange:v=>h(v.currentTarget.value),placeholder:"Confirm password...",className:E.input})]}),e("div",{className:E.actions,children:[e(S,{variant:"primary",onClick:d,loading:i,disabled:i,children:t?"Update Password":"Set Password"}),t&&e(S,{variant:"danger",onClick:l,loading:i,disabled:i,children:"Logout"}),t&&e(S,{variant:"secondary",onClick:P,loading:i,disabled:i,children:"Remove Password"})]}),m&&e("p",{className:E.status,children:m})]})]})},ya=()=>{const[t,o]=s(""),[c,g]=s(!0),[p,h]=s(!1),[k,y]=s("");G(()=>{J("/api/auth/app-status").then(r=>o(String(r.port??3e3))).catch(()=>y("Failed to load current port")).finally(()=>g(!1))},[]);const i=async()=>{const r=Number(t);if(!Number.isInteger(r)||r<1||r>65535){y("Enter a port between 1 and 65535");return}h(!0),y("");try{await C.auth.setServerPort.mutate({port:r}),y(`Saved. Restart dango, then open http://localhost:${r} - this overrides the PORT environment variable.`)}catch(m){y(m.message)}finally{h(!1)}};return c?e("div",{className:L.sectionCard,children:e("p",{children:"Loading..."})}):e("div",{className:L.sectionCard,children:[e("h3",{children:"Server Port"}),e("p",{children:"Port the backend listens on. Takes effect after a restart. Google and AniList sign-in need the matching redirect URI registered with the provider."}),e("div",{className:E.settingItem,children:[e("div",{className:E.field,children:[e("label",{htmlFor:"server-port",children:"Port"}),e("input",{id:"server-port",type:"number",min:1,max:65535,value:t,onChange:r=>o(r.currentTarget.value),className:E.input})]}),e("div",{className:E.actions,children:e(S,{variant:"primary",onClick:i,loading:p,disabled:p,children:"Save Port"})}),k&&e("p",{className:E.status,children:k})]})]})},va=()=>{const{theme:t,setTheme:o,loading:c}=Fe();return e("div",{children:[e("h4",{style:{margin:"0 0 0.25rem",fontSize:"1rem"},children:"Palette"}),e("p",{style:{margin:"0 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Taro is the default. Pick a palette that suits you."}),e("div",{role:"radiogroup","aria-label":"Palette",style:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(150px, 1fr))",gap:"0.6rem"},children:$e.map(g=>{const p=t===g.id;return e("button",{role:"radio","aria-checked":p,disabled:c,onClick:()=>o(g.id),style:{display:"flex",gap:"0.6rem",alignItems:"center",textAlign:"left",padding:"0.65rem 0.75rem",borderRadius:"10px",cursor:"pointer",background:p?"var(--accent-subtle)":"var(--bg-tertiary)",border:p?"1px solid var(--accent)":"1px solid var(--border-primary)",color:"var(--text-primary)"},children:[e("span",{"aria-hidden":!0,style:{width:26,height:26,borderRadius:"50%",flex:"none",background:g.swatch,border:"1px solid rgba(0,0,0,0.35)"}}),e("span",{style:{minWidth:0},children:[e("span",{style:{display:"block",fontSize:"0.85rem",fontWeight:700},children:g.label}),e("span",{style:{display:"block",fontSize:"0.75rem",color:"var(--text-secondary)",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:g.blurb})]})]},g.id)})})]})};function wa({variant:t="info",children:o,className:c=""}){return e("div",{className:`alert alert-${t} ${c}`,children:o})}const ba={anime:"Watchlist",manga:"Reading List",tv:"TV Watchlist",asmr:"Listening List"},Ne=["general","presence","server","sync","watchlist","database"],La=()=>{const{data:t}=pe(ee),[o,c]=qe(),{contentType:g}=Te(),p=o.get("tab"),[h,k]=s(p&&Ne.includes(p)?p:"general"),[y,i]=s(""),r=Z(null),m=Z(null),f=Z(new Map),[d,P]=s({top:0,height:0,left:0,width:0}),{lowEndMode:l,setLowEndMode:v}=He(),{hasConsent:_,grant:T,revoke:O}=We(),[I,a]=s(!1),[N,R]=s(Be),[q,x]=s(!0),{data:A}=le("discordRPCEnabled"),M=_e(),[j,Q]=s(!0),{data:b}=le("dangoGaze"),[Le,fe]=s(!0),{data:ae}=le("discordRPCHideMature"),[ye,ie]=s(""),[ne,oe]=s(null);G(()=>{t?.owner&&C.discord.gatewayStatus.query().then(n=>{oe(n),n.masked&&n.masked!=="none"&&ie(n.masked)}).catch(()=>{})},[t?.owner]),G(()=>{A!==void 0&&x(A==="true"||A===!0||A===null)},[A]),G(()=>{ae!==void 0&&fe(ae==="true"||ae===!0||ae===null)},[ae]);const Pe=n=>{x(n),M.mutate({key:"discordRPCEnabled",value:String(n)})};G(()=>{b!==void 0&&Q(b!=="false"&&b!==!1)},[b]);const Ie=n=>{Q(n),M.mutate({key:"dangoGaze",value:String(n)})},xe=n=>{fe(n),M.mutate({key:"discordRPCHideMature",value:String(n)})},Re=n=>{R(n),je.setItem(Qe,String(n)),window.dispatchEvent(new CustomEvent(Ve))};we.useEffect(()=>{document.title="Settings - dango"},[]),we.useEffect(()=>{const n=o.get("tab");n&&Ne.includes(n)&&k(n)},[o]);const V=n=>{k(n),c(n==="general"?{}:{tab:n})},re=me(()=>{const n=f.current.get(h),z=m.current;if(n&&z){const Y=z.getBoundingClientRect(),F=n.getBoundingClientRect(),se=window.matchMedia("(max-width: 900px)").matches;P(se?{top:F.top-Y.top,height:F.height,left:F.left-Y.left,width:F.width}:{top:F.top-Y.top,height:F.height,left:0,width:0})}},[h]);ze(()=>{re()},[h,re]),G(()=>{const n=()=>re();window.addEventListener("resize",n);let z=!1;return document.fonts?.ready&&document.fonts.ready.then(()=>{z||re()}),()=>{z=!0,window.removeEventListener("resize",n)}},[h,re]);const De=()=>{i("Exporting databases...");const n=window.DangoBridge;if(n?.downloadFile){n.downloadFile("/api/backup-db","dango-backup.json"),setTimeout(()=>{i("Databases exported successfully!")},1500);return}const z=document.createElement("a");z.href="/api/backup-db",z.download="dango-backup.json",document.body.appendChild(z),z.click(),z.remove(),setTimeout(()=>{i("Databases exported successfully!")},1500)},Ae=async n=>{const z=n.currentTarget.files?.[0];if(!z)return;i("Importing databases...");const Y=new FormData;Y.append("dbfile",z);try{const F=await X("/api/restore-db",{method:"POST",body:Y}),se=await F.json();if(F.ok){const ve=Array.isArray(se.restored)?se.restored.join(", "):null;i(ve?`Databases imported successfully (${ve})!`:"Database imported successfully!"),setTimeout(()=>window.location.reload(),2e3)}else i(`Import failed: ${se.error}`)}catch{i("Import failed: An unexpected error occurred.")}finally{n.currentTarget.value=""}},Oe=()=>{r.current?.click()},Ge=()=>{switch(h){case"general":return e("div",{className:u.tabContent,children:[e(et,{}),e("div",{className:L.sectionCard,children:[e("h3",{children:"Appearance & Preferences"}),e("p",{children:"Configure how titles are displayed and other general preferences."}),e("div",{className:u.settingItem,children:e(tt,{})}),e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e(va,{})}),e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Low End Mode"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Disables animations and heavy visual effects for better performance on older hardware."})]}),e($,{isChecked:l,onChange:n=>v(n.currentTarget.checked),id:"low-end-mode"})]})}),e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Dango Animations"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Lets the dango logo look around, blink and react when you pet it. Always off in Low End Mode."})]}),e($,{isChecked:j,onChange:n=>Ie(n.currentTarget.checked),id:"dango-gaze"})]})}),e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Virtual Keyboard"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Shows an on-screen keyboard when text search fields are focused."})]}),e($,{isChecked:N,onChange:n=>Re(n.currentTarget.checked),id:"virtual-keyboard-enabled"})]})})]}),e("section",{className:L.sectionCard,children:[e("h3",{children:"Keyboard Shortcuts"}),e("p",{children:"Use S or Ctrl+K to focus search anywhere, or use player keys while watching."}),e("div",{className:u.shortcutContainer,children:[e("div",{className:u.shortcutGroup,children:[e("h4",{className:u.shortcutGroupTitle,children:"Search"}),e("div",{className:u.shortcutGrid,children:[e("div",{className:u.shortcutCard,children:[e("kbd",{children:"S"}),e("span",{children:"Focus search"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"Ctrl + K / ⌘ + K"}),e("span",{children:"Focus search"})]})]})]}),e("div",{className:u.shortcutGroup,children:[e("h4",{className:u.shortcutGroupTitle,children:"Player"}),e("div",{className:u.shortcutGrid,children:[e("div",{className:u.shortcutCard,children:[e("kbd",{children:"Space / K"}),e("span",{children:"Play / pause"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"J / L · ← / →"}),e("span",{children:"Seek back / fwd"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"↑ / ↓"}),e("span",{children:"Adjust volume"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"M / F"}),e("span",{children:"Mute / fullscreen"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"N / P"}),e("span",{children:"Next / prev episode"})]}),e("div",{className:u.shortcutCard,children:[e("kbd",{children:"T"}),e("span",{children:"Theater mode"})]})]})]})]})]})]});case"presence":return e("div",{className:u.tabContent,children:e("div",{className:L.sectionCard,children:[e("h3",{children:"Presence & Content"}),e("p",{children:"Control what Dango shares on Discord and your mature-content preference."}),t?.owner&&e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Rich Presence"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Show your current anime and watch progress on your Discord profile status."})]}),e($,{isChecked:q,onChange:n=>Pe(n.currentTarget.checked),id:"discord-rpc-enabled"})]})}),t?.owner&&q&&e("div",{className:u.settingItem,style:{marginTop:"1rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Hide Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Hide mature content (18+) from Discord Rich Presence."})]}),e($,{isChecked:Le,onChange:n=>xe(n.currentTarget.checked),id:"discord-hide-mature"})]})}),t?.owner&&e("div",{className:u.settingItem,style:{marginTop:"1.5rem",background:"var(--bg-tertiary)",padding:"1rem",borderRadius:"8px",border:"1px solid var(--border-color)"},children:[e("div",{className:L.settingRow,children:e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Discord Mobile Presence (Gateway)"}),e("p",{style:{margin:"0.25rem 0 0.75rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Paste your Discord authentication token to enable presence on mobile devices. If no token is saved, the default desktop Rich Presence is used. The token is stored locally in your configuration and never shared."})]})}),e(wa,{variant:"warning",style:{marginTop:"1.25rem",paddingTop:"1.25rem"},children:[e("strong",{children:"Use at your own risk."})," This feature uses the Discord Gateway API with your user token, which violates Discord's Terms of Service. Discord may detect this usage and take action against your account, including phone number locks, temporary suspensions, or permanent bans. While the risk is generally low, it is not zero. Only use this if you understand and accept the risks."]}),e("div",{style:{marginTop:"0.75rem",display:"flex",gap:"0.5rem",alignItems:"center",flexWrap:"wrap"},children:[e("input",{type:"password",value:ye,onChange:n=>ie(n.currentTarget.value),placeholder:"Paste Discord token here...",style:{flex:"1 1 200px",padding:"0.5rem",borderRadius:"4px",border:"1px solid var(--border-color)",background:"var(--bg-primary)",color:"var(--text-primary)",fontFamily:"monospace",minWidth:0}}),e(S,{variant:"primary",size:"sm",onClick:async()=>{try{const n=await C.discord.gatewaySave.mutate({token:ye});oe({hasToken:!0,masked:n.masked,enabled:!0}),ie(n.masked)}catch(n){alert(n instanceof Error?n.message:"Failed to save token")}},children:"Save"}),e(S,{variant:"secondary",size:"sm",onClick:async()=>{await C.discord.gatewayRemove.mutate().catch(()=>{}),ie(""),oe({hasToken:!1,masked:null,enabled:!1})},children:"Remove"})]}),ne&&e("p",{style:{marginTop:"0.5rem",fontSize:"0.8rem",color:ne.hasToken?"green":"var(--text-secondary)"},children:["Status:"," ",ne.hasToken?`Token saved (${ne.masked})`:"No token saved",ne.enabled?" - Gateway active":""]}),t?.owner&&e(da,{})]}),e("div",{className:u.settingItem,style:{marginTop:"1.5rem"},children:e("div",{className:L.settingRow,children:[e("div",{style:{minWidth:0},children:[e("h4",{style:{margin:0,fontSize:"1rem"},children:"Mature Content"}),e("p",{style:{margin:"0.25rem 0 0",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Allow mature content intended for adults 18 and older. Turning this off restores filtering and blur gates."})]}),e($,{isChecked:_,onChange:n=>{n.currentTarget.checked?a(!0):(O(),window.location.reload())},id:"mature-content-enabled"})]})})]})});case"server":return e("div",{className:u.tabContent,children:[t?.owner&&e(fa,{}),t?.owner&&e(ya,{})]});case"sync":return e("div",{className:u.tabContent,children:[e(la,{}),e(Rt,{}),e(Dt,{}),t?.owner&&e(oa,{})]});case"watchlist":return e("div",{className:u.tabContent,children:e(Et,{})});case"database":return e("div",{className:u.tabContent,children:[e("div",{className:L.sectionCard,children:[e("h3",{children:"Database Management"}),e("p",{children:"Download a backup of all databases (anime, manga, TV and ASMR) or restore from a backup file. Legacy single-file anime (.db) backups can still be restored."}),e("div",{className:u.controls,children:[e(S,{onClick:De,children:"Backup Database"}),e(S,{variant:"secondary",onClick:Oe,children:"Restore Database"})]}),e("input",{type:"file",ref:r,onChange:Ae,style:{position:"absolute",width:1,height:1,opacity:0,overflow:"hidden"},accept:".json,.db,application/octet-stream"}),y&&e("p",{className:u.status,children:y})]}),t?.owner&&e(aa,{}),e(ia,{})]});default:return null}};return e("div",{className:"page-container",children:[e("div",{className:u.settingsHeader,children:[e("h1",{className:u.pageTitle,children:"Settings"}),e("p",{className:u.pageSubtitle,children:"Manage your preferences and data synchronization"})]}),e("div",{className:u.settingsLayout,children:[e("aside",{className:u.sidebar,ref:m,children:[e("div",{className:u.sidebarIndicator,style:{top:d.top,height:d.height,left:d.left,...d.width?{width:d.width}:{}}}),e("button",{ref:n=>{n&&f.current.set("general",n)},className:`${u.sidebarItem} ${h==="general"?u.active:""}`,onClick:()=>V("general"),children:[e(B,{name:"cog"})," ",e("span",{children:"General"})]}),e("button",{ref:n=>{n&&f.current.set("presence",n)},className:`${u.sidebarItem} ${h==="presence"?u.active:""}`,onClick:()=>V("presence"),children:[e(B,{name:"discord"})," ",e("span",{children:"Presence"})]}),e("button",{ref:n=>{n&&f.current.set("server",n)},className:`${u.sidebarItem} ${h==="server"?u.active:""}`,onClick:()=>V("server"),children:[e(B,{name:"server"})," ",e("span",{children:"Server"})]}),e("button",{ref:n=>{n&&f.current.set("sync",n)},className:`${u.sidebarItem} ${h==="sync"?u.active:""}`,onClick:()=>V("sync"),children:[e(B,{name:"cloud"})," ",e("span",{children:"Synchronization"})]}),e("button",{ref:n=>{n&&f.current.set("watchlist",n)},className:`${u.sidebarItem} ${h==="watchlist"?u.active:""}`,onClick:()=>V("watchlist"),children:[e(B,{name:"list"})," ",e("span",{children:ba[g]})]}),e("button",{ref:n=>{n&&f.current.set("database",n)},className:`${u.sidebarItem} ${h==="database"?u.active:""}`,onClick:()=>V("database"),children:[e(B,{name:"database"})," ",e("span",{children:"Database"})]})]}),e("main",{className:u.mainContent,children:e("div",{className:u.tabContent,children:Ge()},h)})]}),e(Ye,{isOpen:I,onClose:()=>a(!1),onGrant:()=>{T(),a(!1)},scope:"section"})]})};export{La as default};
@@ -1 +1 @@
1
- import{u as o,g as r}from"./vendor-core-DfaOB3Rn.js";import{u as l}from"./index-BR99iwWT.js";const a="_skeletonCard_qtypb_1",i="_poster_qtypb_11",d="_line_qtypb_20",c="_info_qtypb_38",_="_short_qtypb_54",m="_lowEnd_qtypb_69",e={skeletonCard:a,poster:i,line:d,"skeleton-wave":"_skeleton-wave_qtypb_1",info:c,short:_,lowEnd:m},p=({layout:n="vertical"})=>{const{lowEndMode:t}=l();return o("div",{className:`${e.skeletonCard} ${e[n]} ${t?e.lowEnd:""}`,children:[o("div",{className:e.poster}),o("div",{className:e.info,children:[o("div",{className:e.line}),o("div",{className:`${e.line} ${e.short}`})]})]})},v=({count:n=14,layout:t="vertical"})=>o("div",{className:"grid-container",children:Array.from({length:n}).map((k,s)=>o(p,{layout:t},s))}),w=r.memo(v);export{p as A,w as S};
1
+ import{u as o,g as r}from"./vendor-core-DfaOB3Rn.js";import{u as l}from"./index-fS4AGBy2.js";const a="_skeletonCard_qtypb_1",i="_poster_qtypb_11",d="_line_qtypb_20",c="_info_qtypb_38",_="_short_qtypb_54",m="_lowEnd_qtypb_69",e={skeletonCard:a,poster:i,line:d,"skeleton-wave":"_skeleton-wave_qtypb_1",info:c,short:_,lowEnd:m},p=({layout:n="vertical"})=>{const{lowEndMode:t}=l();return o("div",{className:`${e.skeletonCard} ${e[n]} ${t?e.lowEnd:""}`,children:[o("div",{className:e.poster}),o("div",{className:e.info,children:[o("div",{className:e.line}),o("div",{className:`${e.line} ${e.short}`})]})]})},v=({count:n=14,layout:t="vertical"})=>o("div",{className:"grid-container",children:Array.from({length:n}).map((k,s)=>o(p,{layout:t},s))}),w=r.memo(v);export{p as A,w as S};
@@ -0,0 +1 @@
1
+ ._header_azjok_1{margin-bottom:var(--space-8);animation:_fadeIn_azjok_1 .8s var(--ease-smooth)}._pageTitle_azjok_6{font-size:var(--font-size-xl);font-weight:800;color:var(--text-primary);margin:0 0 var(--space-2);letter-spacing:-.02em}._pageSubtitle_azjok_14{color:var(--text-tertiary);font-size:var(--font-size-sm);margin:0}._importCard_azjok_20{padding:var(--space-8) 0;border-top:1px solid var(--border-primary);animation:_fadeIn_azjok_1 .4s var(--ease-smooth)}._importCard_azjok_20:first-of-type{border-top:none;padding-top:var(--space-4)}._cardHeader_azjok_31{margin-bottom:var(--space-4)}._cardHeader_azjok_31 h3{margin:0 0 var(--space-2);font-size:var(--font-size-lg);font-weight:700;color:var(--text-primary)}._cardHeader_azjok_31 p{color:var(--text-secondary);font-size:var(--font-size-sm);margin:0;line-height:1.6}._uploadArea_azjok_49{margin-bottom:var(--space-6)}._fileInputWrapper_azjok_53{position:relative;display:flex;align-items:center;gap:var(--space-3)}._fileInput_azjok_53{position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;z-index:2}._fileDisplay_azjok_71{flex:1;display:flex;align-items:center;gap:var(--space-3);overflow:hidden}._fileIcon_azjok_79{color:var(--text-tertiary);font-size:1.5rem}._fileName_azjok_84{color:var(--text-primary);font-size:var(--font-size-sm);font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._browseButton_azjok_93{background:#ffffff0d;border:1px solid var(--border-primary);color:var(--text-secondary);padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);font-size:var(--font-size-sm);font-weight:600;pointer-events:none}._optionsArea_azjok_104{margin-bottom:var(--space-5);margin-top:var(--space-4);display:flex;flex-direction:column;gap:var(--space-4)}._checkboxLabel_azjok_112{display:flex;align-items:flex-start;gap:var(--space-3);cursor:pointer;position:relative}._checkbox_azjok_112{opacity:0;position:absolute}._checkboxCustom_azjok_125{width:20px;height:20px;border:2px solid var(--border-secondary);border-radius:4px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px;transition:all var(--transition-fast)}._checkbox_azjok_112:checked+._checkboxCustom_azjok_125{background:var(--color-warning);border-color:var(--color-warning)}._checkbox_azjok_112:checked+._checkboxCustom_azjok_125:after{content:"";width:5px;height:10px;border:solid var(--color-warning-text);border-width:0 2px 2px 0;transform:rotate(45deg);margin-bottom:2px}._optionText_azjok_153{display:flex;flex-direction:column;gap:4px}._optionTitle_azjok_159{color:var(--color-warning);font-weight:600;font-size:var(--font-size-sm)}._optionDesc_azjok_165{color:var(--text-tertiary);font-size:.8rem;line-height:1.4}._actions_azjok_171{display:flex;justify-content:flex-end;gap:var(--space-3);border-top:1px solid var(--border-primary);padding-top:var(--space-6)}._importBtn_azjok_179{display:flex;align-items:center;gap:var(--space-2)}._cancelBtn_azjok_185{display:flex;align-items:center;gap:var(--space-2);background:color-mix(in srgb,var(--color-danger) 15%,transparent);border-color:color-mix(in srgb,var(--color-danger) 30%,transparent);color:var(--color-danger)}._cancelBtn_azjok_185:hover{background:color-mix(in srgb,var(--color-danger) 25%,transparent);border-color:color-mix(in srgb,var(--color-danger) 50%,transparent)}._statusMessage_azjok_199{margin-top:var(--space-6);padding:var(--space-4);border-radius:var(--radius-md);font-size:var(--font-size-sm);font-weight:500;text-align:center;animation:_fadeIn_azjok_1 .3s ease}._statusMessage_azjok_199._success_azjok_209{background:color-mix(in srgb,var(--color-success) 10%,transparent);color:var(--color-success);border:1px solid color-mix(in srgb,var(--color-success) 20%,transparent)}._statusMessage_azjok_199._error_azjok_215{background:color-mix(in srgb,var(--color-danger) 10%,transparent);color:var(--color-danger);border:1px solid color-mix(in srgb,var(--color-danger) 20%,transparent)}._progressSection_azjok_221{margin-top:var(--space-6);animation:_fadeIn_azjok_1 .3s ease}._progressBar_azjok_226{height:6px;background:var(--bg-tertiary);border-radius:3px;overflow:hidden;margin-bottom:var(--space-3)}._progressFill_azjok_234{height:100%;background:linear-gradient(90deg,#6366f1,#8b5cf6);border-radius:3px;transition:width .3s ease}._progressInfo_azjok_241{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}._progressCount_azjok_248{font-size:var(--font-size-sm);color:var(--text-tertiary);font-weight:500;white-space:nowrap}._progressTitle_azjok_255{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm);color:var(--text-primary);font-weight:500;text-align:right;overflow:hidden}._progressTitle_azjok_255>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:300px}._sourceBadge_azjok_273{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;flex-shrink:0}._sourceBadge_azjok_273._anilist_azjok_285{background:#6366f126;color:#818cf8;border:1px solid rgba(99,102,241,.3)}._sourceBadge_azjok_273._kitsu_azjok_291{background:#ec489926;color:#f472b6;border:1px solid rgba(236,72,153,.3)}._sourceBadge_azjok_273._offline_azjok_297{background:#22c55e26;color:#4ade80;border:1px solid rgba(34,197,94,.3)}._skipped_azjok_303{color:var(--text-tertiary);font-style:italic}._cardTitleRow_azjok_308{display:flex;align-items:center;gap:var(--space-3)}._cardTitleRow_azjok_308 h3{margin:0}._anilistIcon_azjok_318{font-size:1.5rem;color:#818cf8;flex-shrink:0}._malIcon_azjok_324{font-size:1.5rem;color:#2e51a2;flex-shrink:0}._badgeOnline_azjok_330{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:3px 10px;border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-success) 12%,transparent);color:var(--color-success);border:1px solid color-mix(in srgb,var(--color-success) 25%,transparent)}._badgeOffline_azjok_342{font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;padding:3px 10px;border-radius:var(--radius-full);background:var(--bg-tertiary);color:var(--text-tertiary);border:1px solid var(--border-primary)}._connectedProfile_azjok_354{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0}._avatar_azjok_361{width:48px;height:48px;border-radius:50%;flex-shrink:0}._connectedInfo_azjok_368{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0}._connectedName_azjok_376{color:var(--text-primary);font-weight:700;font-size:var(--font-size-sm)}._connectedHint_azjok_382{color:var(--color-success);font-size:.8rem}._loginPrompt_azjok_387{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);flex-wrap:wrap}._loginSection_azjok_395{display:flex;flex-direction:column;gap:var(--space-3)}._loginSection_azjok_395>._primaryBtn_azjok_401{align-self:flex-start}._fieldLabel_azjok_405{font-size:var(--font-size-sm);font-weight:600;color:var(--text-primary)}._fieldLabel_azjok_405 a{color:var(--accent);text-decoration:none;display:inline-flex;align-items:center;gap:4px;margin-left:6px}._fieldLabel_azjok_405 a:hover{text-decoration:underline}._helpText_azjok_424{margin:0;font-size:.8rem;color:var(--text-tertiary);line-height:1.6}._resetBtn_azjok_431{align-self:flex-start;padding:0;border:0;background:none;color:var(--accent);font-size:var(--font-size-sm);cursor:pointer;text-decoration:underline}._resetBtn_azjok_431:hover:not(:disabled){filter:brightness(1.1)}._resetBtn_azjok_431:disabled{opacity:.5;cursor:not-allowed}._helpText_azjok_424 code{background:var(--bg-tertiary);border:1px solid var(--border-primary);border-radius:4px;padding:1px 6px;font-size:.75rem;color:var(--text-secondary);word-break:break-all}._loginText_azjok_461{color:var(--text-secondary);font-size:var(--font-size-sm);margin:0;line-height:1.6;flex:1;min-width:220px}._primaryBtn_azjok_401,._secondaryBtn_azjok_471,._syncBtn_azjok_472{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-2-5) var(--space-4);border-radius:var(--radius-md);font-weight:600;font-size:var(--font-size-sm);cursor:pointer;border:1px solid transparent;transition:all var(--transition-fast);flex-shrink:0}._primaryBtn_azjok_401{background:var(--accent);color:var(--accent-text)}._primaryBtn_azjok_401:hover{filter:brightness(1.1)}._secondaryBtn_azjok_471{background:#ffffff0d;border-color:var(--border-primary);color:var(--text-primary)}._secondaryBtn_azjok_471:hover:not(:disabled){background:var(--bg-elevated);border-color:var(--border-secondary)}._syncBtn_azjok_472{background:linear-gradient(135deg,#6366f1,#8b5cf6);color:#fff;padding:var(--space-3) var(--space-6);margin-top:var(--space-2)}._syncBtn_azjok_472:hover:not(:disabled){filter:brightness(1.1)}._primaryBtn_azjok_401:disabled,._secondaryBtn_azjok_471:disabled,._syncBtn_azjok_472:disabled{opacity:.5;cursor:not-allowed}._divider_azjok_525{border:0;border-top:1px solid var(--border-primary);margin:var(--space-6) 0}._actionSection_azjok_531 h4{margin:0 0 var(--space-1);color:var(--text-primary);font-size:var(--font-size-sm);font-weight:700}._actionSection_azjok_531 p{color:var(--text-secondary);font-size:var(--font-size-sm);margin:0 0 var(--space-4);line-height:1.6}._inputGroup_azjok_545{display:flex;gap:var(--space-2);margin-bottom:var(--space-4)}._credentialFields_azjok_551{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-3)}._credentialField_azjok_551{display:flex;flex-direction:column;justify-content:flex-end;gap:var(--space-2);min-width:0}._credentialField_azjok_551 ._input_azjok_545{flex:none;width:100%;box-sizing:border-box}._input_azjok_545{flex:1;min-width:0;padding:var(--space-2-5) var(--space-3);border-radius:var(--radius-md);border:1px solid var(--border-primary);background:var(--bg-tertiary);color:var(--text-primary);font-size:var(--font-size-sm)}._input_azjok_545:focus{outline:none;border-color:var(--accent)}._syncSummary_azjok_587{margin-top:var(--space-3);font-size:.8rem;color:var(--text-tertiary)}._syncErrors_azjok_593{color:var(--color-danger)}._spin_azjok_597{animation:_spin_azjok_597 1s linear infinite}@keyframes _spin_azjok_597{to{transform:rotate(360deg)}}@keyframes _fadeIn_azjok_1{0%{opacity:0}to{opacity:1}}._radioGroup_azjok_616{display:flex;gap:var(--space-4);margin-bottom:var(--space-5);padding:var(--space-1) 0}._radioLabel_azjok_623{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm);color:var(--text-secondary);cursor:pointer;-webkit-user-select:none;user-select:none}._radioLabel_azjok_623 input[type=radio]{appearance:none;-webkit-appearance:none;width:16px;height:16px;border:2px solid var(--border-secondary);border-radius:50%;background:transparent;cursor:pointer;position:relative;flex-shrink:0}._radioLabel_azjok_623 input[type=radio]:checked{border-color:var(--accent)}._radioLabel_azjok_623 input[type=radio]:checked:after{content:"";position:absolute;top:3px;left:3px;width:6px;height:6px;border-radius:50%;background:var(--accent)}._syncHint_azjok_661{color:var(--text-secondary);font-size:var(--font-size-sm);margin:0 0 var(--space-4);line-height:1.6}._importLoading_azjok_668{display:flex;align-items:center;gap:var(--space-2);font-size:var(--font-size-sm);color:var(--text-secondary);margin-top:var(--space-3)}@media(max-width:600px){._credentialFields_azjok_551{grid-template-columns:1fr}}._primaryBtn_azjok_401:focus-visible,._secondaryBtn_azjok_471:focus-visible,._syncBtn_azjok_472:focus-visible,._input_azjok_545:focus-visible,._checkboxCustom_azjok_125:focus-within,._resetBtn_azjok_431:focus-visible{outline:2px solid var(--accent);outline-offset:3px}._checkboxLabel_azjok_112:focus-within ._checkboxCustom_azjok_125{outline:2px solid var(--accent);outline-offset:2px}
@@ -0,0 +1,2 @@
1
+ import{h as J,d as i,A as ye,u as e,S as g,g as ea,q as De}from"./vendor-core-DfaOB3Rn.js";import{u as V,b as R,a as S}from"./vendor-query-BBT5_sHx.js";import{F as r,q as s,t as c,ad as aa,n as na,S as qe,B as ge}from"./index-fS4AGBy2.js";import{I as m}from"./vendor-icons-DrybRNxP.js";function ta(){const N=V();J(()=>{const C=new URLSearchParams(window.location.search),h=C.get("mal");if(!h)return;const t=C.get("user"),y=C.get("reason");window.history.replaceState(null,"",window.location.pathname),h==="success"?(r.success(t?`Connected to MyAnimeList as ${decodeURIComponent(t)}`:"Connected to MyAnimeList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(y?decodeURIComponent(y):"MyAnimeList authentication failed")},[N])}function sa(){const N=V(),[C,h]=i(!1);return J(()=>{const t=new URLSearchParams(window.location.search),y=t.get("anilist");if(y){const k=t.get("user"),u=t.get("reason");window.history.replaceState(null,"",window.location.pathname),y==="success"?(r.success(k?`Connected to AniList as ${decodeURIComponent(k)}`:"Connected to AniList"),N.invalidateQueries({queryKey:[s.trackerStatus]})):r.error(u?decodeURIComponent(u):"AniList authentication failed");return}const b=new URLSearchParams(window.location.hash.substring(1)),l=b.get("access_token"),L=t.get("code");if(!l&&!L){const k=b.get("error");k&&(r.error(`AniList error: ${k}`),window.history.replaceState(null,"",window.location.pathname));return}const d=window.location.origin+window.location.pathname;window.history.replaceState(null,"",window.location.pathname),h(!0),r("Connecting to AniList..."),c.tracker.anilistAuth.mutate(l?{token:l}:{code:L,redirectUri:d}).then(async k=>{const u=k.user;r.success(`Connected to AniList as ${u?.name??"AniList user"}`),N.invalidateQueries({queryKey:[s.trackerStatus]})}).catch(k=>{r.error(k instanceof Error?k.message:"Failed to authenticate with AniList")}).finally(()=>{h(!1)})},[N]),C}const ia="_header_azjok_1",ra="_fadeIn_azjok_1",ca="_pageTitle_azjok_6",oa="_pageSubtitle_azjok_14",la="_importCard_azjok_20",da="_cardHeader_azjok_31",ma="_uploadArea_azjok_49",ua="_fileInputWrapper_azjok_53",pa="_fileInput_azjok_53",ha="_fileDisplay_azjok_71",ga="_fileIcon_azjok_79",ya="_fileName_azjok_84",ka="_browseButton_azjok_93",fa="_optionsArea_azjok_104",_a="_checkboxLabel_azjok_112",ba="_checkbox_azjok_112",va="_checkboxCustom_azjok_125",Na="_optionText_azjok_153",wa="_optionTitle_azjok_159",Ca="_optionDesc_azjok_165",Ia="_actions_azjok_171",Sa="_importBtn_azjok_179",La="_cancelBtn_azjok_185",Ma="_statusMessage_azjok_199",xa="_success_azjok_209",Ta="_error_azjok_215",Aa="_progressSection_azjok_221",za="_progressBar_azjok_226",Pa="_progressFill_azjok_234",ja="_progressInfo_azjok_241",Ba="_progressCount_azjok_248",Ea="_progressTitle_azjok_255",Fa="_sourceBadge_azjok_273",Da="_anilist_azjok_285",qa="_kitsu_azjok_291",$a="_offline_azjok_297",Ka="_skipped_azjok_303",Ra="_cardTitleRow_azjok_308",Ua="_anilistIcon_azjok_318",Qa="_malIcon_azjok_324",Oa="_badgeOnline_azjok_330",Ha="_badgeOffline_azjok_342",Ga="_connectedProfile_azjok_354",Wa="_avatar_azjok_361",Xa="_connectedInfo_azjok_368",Ya="_connectedName_azjok_376",Ja="_connectedHint_azjok_382",Va="_loginPrompt_azjok_387",Za="_loginSection_azjok_395",en="_primaryBtn_azjok_401",an="_fieldLabel_azjok_405",nn="_helpText_azjok_424",tn="_resetBtn_azjok_431",sn="_loginText_azjok_461",rn="_secondaryBtn_azjok_471",cn="_syncBtn_azjok_472",on="_divider_azjok_525",ln="_actionSection_azjok_531",dn="_inputGroup_azjok_545",mn="_credentialFields_azjok_551",un="_credentialField_azjok_551",pn="_input_azjok_545",hn="_syncSummary_azjok_587",gn="_syncErrors_azjok_593",yn="_spin_azjok_597",kn="_radioGroup_azjok_616",fn="_radioLabel_azjok_623",_n="_syncHint_azjok_661",bn="_importLoading_azjok_668",a={header:ia,fadeIn:ra,pageTitle:ca,pageSubtitle:oa,importCard:la,cardHeader:da,uploadArea:ma,fileInputWrapper:ua,fileInput:pa,fileDisplay:ha,fileIcon:ga,fileName:ya,browseButton:ka,optionsArea:fa,checkboxLabel:_a,checkbox:ba,checkboxCustom:va,optionText:Na,optionTitle:wa,optionDesc:Ca,actions:Ia,importBtn:Sa,cancelBtn:La,statusMessage:Ma,success:xa,error:Ta,progressSection:Aa,progressBar:za,progressFill:Pa,progressInfo:ja,progressCount:Ba,progressTitle:Ea,sourceBadge:Fa,anilist:Da,kitsu:qa,offline:$a,skipped:Ka,cardTitleRow:Ra,anilistIcon:Ua,malIcon:Qa,badgeOnline:Oa,badgeOffline:Ha,connectedProfile:Ga,avatar:Wa,connectedInfo:Xa,connectedName:Ya,connectedHint:Ja,loginPrompt:Va,loginSection:Za,primaryBtn:en,fieldLabel:an,helpText:nn,resetBtn:tn,loginText:sn,secondaryBtn:rn,syncBtn:cn,divider:on,actionSection:ln,inputGroup:dn,credentialFields:mn,credentialField:un,input:pn,syncSummary:hn,syncErrors:gn,spin:yn,radioGroup:kn,radioLabel:fn,syncHint:_n,importLoading:bn},ie="tracker_anilist_client_id",Re="49887".trim(),re=!!Re;function $e(){const N=V(),[C,h]=i(""),t=ye(!1),y=sa(),{data:b}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query()}),{data:l}=R({queryKey:[s.anilistClientId],queryFn:async()=>(await c.settings.getByKey.query({key:ie})).value||""});J(()=>{t.current||l===void 0||(l&&h(l),t.current=!0)},[l]);const L=S({mutationFn:()=>c.tracker.anilistDisconnect.mutate(),onSuccess:()=>{N.invalidateQueries({queryKey:[s.trackerStatus]}),r.success("Disconnected from AniList")},onError:_=>r.error(_.message)}),d=S({mutationFn:()=>c.settings.set.mutate({key:ie,value:""}),onSuccess:()=>{h(""),N.invalidateQueries({queryKey:[s.anilistClientId]}),r.success("Switched to dango's AniList app")},onError:_=>r.error(_.message)}),k=async()=>{const _=C.trim(),o=_||Re;if(!o){r.error("Enter your AniList client ID first");return}const P=(l||"").trim();try{_?_!==l&&await c.settings.set.mutate({key:ie,value:_}):re&&P&&await c.settings.set.mutate({key:ie,value:""}),N.invalidateQueries({queryKey:[s.anilistClientId]})}catch(M){r.error(M.message);return}const p=encodeURIComponent(window.location.origin+window.location.pathname);window.location.href=`https://anilist.co/api/v2/oauth/authorize?client_id=${encodeURIComponent(o)}&response_type=token&state=${p}`},u=b?.anilist?.user??null;return b?.anilist?.connected&&u?e("div",{className:a.connectedProfile,children:[u.avatar&&e("img",{src:u.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:u.name}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>L.mutate(),disabled:L.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:["Log in with AniList to enable bidirectional progress & status synchronization.",y&&e("span",{style:{marginLeft:8,color:"var(--accent)"},children:"Finishing login…"})]}),e("div",{className:a.fieldLabel,children:["AniList client ID - defaults to dango's app"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]})]}),e("div",{className:a.inputGroup,children:[e("input",{type:"text",placeholder:"Client ID",value:C,onChange:_=>h(_.currentTarget.value),className:a.input}),e("button",{className:a.primaryBtn,onClick:k,disabled:!(C.trim()||re),children:[e(m,{name:"external-link-alt"})," Connect"]})]}),re&&l&&e("button",{className:a.resetBtn,onClick:()=>d.mutate(),disabled:d.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:re?e(g,{children:["By default uses dango's client. To use your own AniList app: create it at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste only the ",e("strong",{children:"Client ID"})," above (leave empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://anilist.co/settings/developer",target:"_blank",rel:"noopener noreferrer",children:"anilist.co/settings/developer"}),", set ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:`${window.location.origin}/api/tracker/anilist/callback`}),", then paste the"," ",e("strong",{children:"Client ID"})," above."]})})]})}function Ke({kind:N="anime",active:C=!0}){const h=V(),[t,y]=i(""),[b,l]=i(""),[L,d]=i(""),[k,u]=i(""),_=ye(!1),{data:o}=R({queryKey:[s.malClientConfig],queryFn:()=>c.tracker.malConfig.query()}),{data:P}=R({queryKey:[s.trackerStatus],queryFn:()=>c.tracker.status.query(),refetchInterval:15e3});J(()=>{o&&!_.current&&(y(o.clientId),_.current=!0)},[o]);const p=S({mutationFn:async()=>{d(""),(b.trim()||t.trim()&&t.trim()!==o?.clientId)&&await c.tracker.malSaveConfig.mutate({clientId:t.trim(),clientSecret:b.trim()||void 0}),l("");const f=await c.tracker.malLogin.mutate({redirectUri:`${window.location.origin}/api/tracker/mal/callback`});window.location.assign(f.url)},onError:f=>d(f.message)}),M=S({mutationFn:()=>c.tracker.malDisconnect.mutate(),onSuccess:()=>{h.invalidateQueries({queryKey:[s.trackerStatus]}),u(""),d(""),r.success("Disconnected from MyAnimeList")},onError:f=>d(f.message)}),B=S({mutationFn:()=>c.tracker.malClearConfig.mutate(),onSuccess:()=>{y(""),l(""),u(""),d(""),h.invalidateQueries({queryKey:[s.trackerStatus]}),h.invalidateQueries({queryKey:[s.malClientConfig]}),r.success("Switched to dango's MyAnimeList app - reconnect to finish")},onError:f=>d(f.message)}),D=S({mutationFn:()=>N==="manga"?c.tracker.mangaMalSync.mutate():c.tracker.sync.mutate({provider:"mal"}),onSuccess:f=>{const T=f.summary;u(`Pushed: ${T.pushed} · Pulled: ${T.pulled} · Merged: ${T.merged} · Unchanged: ${T.unchanged}`+(T.errors.length>0?` · ${T.errors.length} error${T.errors.length>1?"s":""}`:""));for(const E of N==="manga"?[[s.trackerStatus],[s.mangaLibrary],[s.mangaContinueReading]]:[[s.trackerStatus],[s.watchlist],[s.continueWatching]])h.invalidateQueries({queryKey:E})},onError:f=>d(f.message)}),x=P?.mal;return e("div",{children:[x?.connected?e(g,{children:[e("div",{className:a.connectedProfile,children:[x.user?.avatar&&e("img",{src:x.user.avatar,alt:"Avatar",className:a.avatar,loading:"lazy",decoding:"async"}),e("div",{className:a.connectedInfo,children:[e("span",{className:a.connectedName,children:x.user?.name||"MyAnimeList user"}),e("span",{className:a.connectedHint,children:"2-way sync is ready"})]}),e("button",{className:a.secondaryBtn,onClick:()=>M.mutate(),disabled:M.isPending,children:[e(m,{name:"sign-out-alt"})," Disconnect"]})]}),C?e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>D.mutate(),disabled:D.isPending,children:[e(m,{name:"sync-alt",className:D.isPending?a.spin:""}),D.isPending?"Syncing...":"Start Sync"]}),k&&e("div",{className:a.syncSummary,children:k})]}):e("p",{className:a.connectedHint,style:{color:"var(--color-warning)"},children:"Not the active tracker - sync disabled."})]}):e("div",{className:a.loginSection,children:[e("p",{className:a.loginText,children:"Log in with MyAnimeList to enable bidirectional progress & status synchronization."}),e("div",{className:a.credentialFields,children:[e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client ID"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:["create your own app ",e(m,{name:"external-link-alt",size:9})]}),o?.mode==="worker"&&e("span",{className:a.helpText,children:" — defaults to dango's app"})]}),e("input",{className:a.input,placeholder:o?.mode==="worker"?"dango's app (leave empty)":"Client ID",value:t,onChange:f=>y(f.currentTarget.value),autoComplete:"off"})]}),e("label",{className:`${a.fieldLabel} ${a.credentialField}`,children:[e("span",{children:["Client secret"," ",o?.hasSecret&&!b&&e("span",{className:a.helpText,children:"— saved"})]}),e("input",{className:a.input,type:"password",value:b,onChange:f=>l(f.currentTarget.value),placeholder:o?.mode==="worker"?"dango's app (leave empty)":o?.hasSecret?"Saved — leave blank to keep":"Client secret",autoComplete:"new-password"})]})]}),o?.hasCustomId&&o?.hasWorker&&e("button",{className:a.resetBtn,onClick:()=>B.mutate(),disabled:B.isPending,children:"Use dango's app instead"}),e("p",{className:a.helpText,children:o?.mode==="worker"?e(g,{children:["By default uses dango's client. To use your own MyAnimeList app: create it at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste its"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above (leave both empty to use dango's)."]}):e(g,{children:["No shipped client in this build - create your own app at"," ",e("a",{href:"https://myanimelist.net/apiconfig",target:"_blank",rel:"noopener noreferrer",children:"myanimelist.net/apiconfig"}),", set its ",e("strong",{children:"Redirect URL"})," to"," ",e("code",{children:[window.location.origin,"/api/tracker/mal/callback"]}),", then paste the"," ",e("strong",{children:"Client ID"})," and ",e("strong",{children:"Client secret"})," above. MAL requires the secret even for PKCE apps; it stays on your dango server and is never returned to the browser."]})}),e("button",{className:a.primaryBtn,onClick:()=>p.mutate(),disabled:!(t.trim()&&b.trim()||o?.clientId&&t.trim()===o.clientId&&o.hasSecret||!t.trim()&&!b.trim()&&o?.mode==="worker")||p.isPending,children:p.isPending?"Connecting...":"Connect to MyAnimeList"})]}),L&&e("p",{className:`${a.helpText} ${a.syncErrors}`,role:"alert",children:L}),e("hr",{className:a.divider}),e("p",{className:a.syncHint,children:"You can also import a public list or XML file without connecting an account:"})]})}const In=()=>{const{setIsOpen:N}=aa(),{contentType:C}=na(),h=C==="manga",t=V();ea.useEffect(()=>{document.title="Trackers - dango"},[]);const[y,b]=i(""),[l,L]=i("username"),[d,k]=i(null),[u,_]=i(!1);ta();const{data:o,isLoading:P}=R({queryKey:[s.trackerStatus],queryFn:async()=>await c.tracker.status.query()}),p=o?.anilist?.connected??!1,M=o?.mal?.connected??!1,{data:B}=R({queryKey:["activeTrackerProvider"],queryFn:async()=>(await c.settings.getByKey.query({key:"active_tracker_provider"}))?.value||""}),D=S({mutationFn:async n=>(await c.settings.set.mutate({key:"active_tracker_provider",value:n}),n),onSuccess:n=>{t.invalidateQueries({queryKey:["activeTrackerProvider"]}),r.success(`Active tracker set to ${n==="mal"?"MyAnimeList":"AniList"}`)},onError:()=>r.error("Failed to update active tracker")}),x=B&&(B==="anilist"&&p||B==="mal"&&M)?B:p&&!M?"anilist":M&&!p?"mal":p?"anilist":"",f=p||M;J(()=>{p&&L("sync")},[p]);const T=S({mutationFn:async()=>(await c.tracker.sync.mutate({provider:"anilist"})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),k(n),r.success(`Sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}`,{duration:6e3})},onError:n=>r.error(n.message)}),[E,ke]=i(""),[Z,fe]=i("sync"),[ce,_e]=i("two-way"),[w,Ue]=i(null),ee=S({mutationFn:async()=>(await c.tracker.mangaSync.mutate({direction:ce})).summary,onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),Ue(n);const v=(n.warnings?.length??0)>0?`, ${n.warnings.length} warning(s)`:"";r.success(`Manga sync complete - pushed ${n.pushed}, pulled ${n.pulled}, merged ${n.merged}, unchanged ${n.unchanged}${v}`,{duration:6e3})},onError:n=>r.error(n.message)}),q=S({mutationFn:async()=>{if(!E.trim())throw new Error("Please enter a username");return(await c.tracker.mangaImport.mutate({username:E.trim(),erase:u})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from AniList`),ke("")},onError:n=>r.error(n.message)}),[U,be]=i(""),[ae,ve]=i("username"),[oe,Ne]=i(null),[ne,we]=i(!1),[Ce,le]=i(""),[Ie,Qe]=i(""),j=S({mutationFn:async()=>{if(!U.trim())throw new Error("Please enter a MAL username");const n=await c.tracker.mangaMalImport.mutate({username:U.trim(),erase:u});return{imported:n.imported??0,skipped:n.skipped??0}},onSuccess:({imported:n,skipped:v})=>{t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]}),r.success(`Imported ${n} manga entries from MAL${v>0?`, skipped ${v}`:""}`),be("")},onError:n=>r.error(n.message)}),Oe=De(async()=>{const n=document.getElementById("malMangaFile");if(!n.files||n.files.length===0){le("Please select a file first.");return}we(!0),le(""),Ne(null);try{const v=new FormData;v.append("xmlfile",n.files[0]),v.append("erase",String(u));const W=await qe("/api/import/mal-xml-manga",{method:"POST",body:v}),I=await W.json().catch(()=>({}));if(!W.ok)throw new Error(I.error||"Import failed");Ne({imported:I.imported??0,skipped:I.skipped??0}),t.invalidateQueries({queryKey:[s.mangaLibrary]}),t.invalidateQueries({queryKey:[s.mangaContinueReading]})}catch(v){le(v.message)}finally{we(!1)}},[u,t]),$=S({mutationFn:async()=>{if(!y.trim())throw new Error("Please enter a username");return(await c.tracker.anilistImport.mutate({username:y.trim(),erase:F})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from AniList`),b("")},onError:n=>r.error(n.message)}),[Q,Se]=i(""),z=S({mutationFn:async n=>{if(!Q.trim())throw new Error("Please enter a MAL username");return(await c.tracker.malImport.mutate({username:Q.trim(),erase:n.erase,useOfflineDb:n.useOfflineDb,skipFallback:n.skipFallback})).count},onSuccess:n=>{t.invalidateQueries({queryKey:[s.watchlist]}),t.invalidateQueries({queryKey:[s.continueWatching]}),r.success(`Imported ${n} anime entries from MAL`),Se("")},onError:n=>r.error(n.message)}),[F,Le]=i(!1),[O,He]=i(!0),[H,Ge]=i(!1),[Me,xe]=i(""),[K,Te]=i(!1),[A,Ae]=i(null),[de,ze]=i(null),[Pe,te]=i(""),me=ye(null),We=n=>{n.currentTarget.files&&n.currentTarget.files.length>0?xe(n.currentTarget.files[0].name):xe("")},Xe=De(async()=>{const n=document.getElementById("malFile");if(!n.files||n.files.length===0){te("Please select a file first.");return}const v=n.files[0];Te(!0),Ae(null),ze(null),te("");const W=new AbortController;me.current=W;try{const I=new FormData;I.append("xmlfile",v),I.append("erase",String(F)),I.append("useOfflineDb",String(O)),I.append("skipFallback",String(H));const ue=await qe("/api/import/mal-xml",{method:"POST",body:I,signal:W.signal});if(!ue.ok){const he=await ue.text();let X="Failed to import";try{X=JSON.parse(he).error||X}catch{}throw new Error(X)}const Be=ue.body?.getReader();if(!Be)throw new Error("No response stream");const Ve=new TextDecoder;let pe="",se="";for(;;){const{done:he,value:X}=await Be.read();if(he)break;pe+=Ve.decode(X,{stream:!0});const Ee=pe.split(`
2
+ `);pe=Ee.pop()||"";for(const Y of Ee)if(Y.startsWith("event: "))se=Y.slice(7).trim();else if(Y.startsWith("data: ")){const Ze=Y.slice(6);try{const Fe=JSON.parse(Ze);se==="progress"?Ae(Fe):se==="complete"&&ze(Fe)}catch{}}else Y===""&&(se="")}t.invalidateQueries({queryKey:[s.watchlist]})}catch(I){I instanceof DOMException&&I.name==="AbortError"?te("Import cancelled."):te(I.message)}finally{Te(!1),me.current=null}},[F,O,H,t]),Ye=()=>{me.current?.abort(),c.settings.malImportCancel.mutate().catch(()=>{})},Je=A?Math.round(A.current/A.total*100):0,[G,je]=i("username");return e("div",{className:"page-container",children:[e("div",{className:a.header,children:[e("h1",{className:a.pageTitle,children:"Trackers"}),e("p",{className:a.pageSubtitle,children:"Import & sync your anime watchlists and manga reading lists with tracking services"})]}),e("div",{style:{marginBottom:"16px",fontSize:"0.8rem",color:"var(--color-warning)",borderBottom:"1px solid var(--border-primary)",paddingBottom:"12px"},children:"⚠ Syncing writes directly to your AniList and MyAnimeList entries, and dango may not always handle anime/manga lists correctly - always keep a backup of your lists before syncing."}),f&&e("div",{style:{marginBottom:"16px",display:"flex",alignItems:"center",gap:"10px",fontSize:"0.85rem"},children:[e("label",{htmlFor:"active-tracker-select",style:{fontWeight:600,color:"var(--text-secondary)"},children:"Active tracker:"}),e("select",{id:"active-tracker-select",value:x,onChange:n=>D.mutate(n.currentTarget.value),style:{padding:"0.3rem 0.5rem",borderRadius:"var(--radius-md)",background:"var(--bg-tertiary)",color:"var(--text-primary)",border:"1px solid var(--border-primary)",fontSize:"var(--font-size-sm)",cursor:"pointer"},children:[p&&e("option",{value:"anilist",children:"AniList"}),M&&e("option",{value:"mal",children:"MyAnimeList"})]})]}),!h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"anilist",className:a.anilistIcon}),e("h3",{children:"AniList"}),P?null:p?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e($e,{}),p&&x!=="anilist"&&e("p",{style:{color:"var(--color-warning)",marginTop:"8px",fontSize:"0.85rem"},children:"Not the active tracker - sync disabled."}),p&&x==="anilist"&&e(g,{children:[e("hr",{className:a.divider}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"username",checked:l==="username",onChange:()=>L("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"anilistMode",value:"sync",checked:l==="sync",onChange:()=>L("sync")}),e("span",{children:"Two-way Sync"})]})]}),l==="username"?e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:y,onChange:n=>b(n.currentTarget.value),className:a.input,disabled:$.isPending,onKeyDown:n=>{n.key==="Enter"&&y.trim()&&$.mutate()}})}):e("p",{className:a.syncHint,children:"Merges progress non-destructively: pushes shows and episodes you watched on dango to AniList, and pulls anything you updated on AniList into dango."}),l==="username"&&e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:F,onChange:n=>Le(n.currentTarget.checked),className:a.checkbox,disabled:$.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Erase current watchlist"}),e("span",{className:a.optionDesc,children:"Delete existing watchlist before importing."})]})]})}),l==="username"?e("button",{className:a.syncBtn,onClick:()=>$.mutate(),disabled:!y.trim()||$.isPending,children:[e(m,{name:"download"}),$.isPending?"Importing...":"Start Import"]}):e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>T.mutate(),disabled:T.isPending,children:[e(m,{name:"sync-alt",className:T.isPending?a.spin:""}),T.isPending?"Syncing...":"Start Sync"]}),d&&e("div",{className:a.syncSummary,children:["Pushed: ",d.pushed," · Pulled: ",d.pulled," · Merged:"," ",d.merged," · Unchanged: ",d.unchanged,d.errors.length>0&&e("span",{className:a.syncErrors,children:[" ","· ",d.errors.length," error",d.errors.length>1?"s":""]})]})]})]})]})}),h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"anilist",className:a.anilistIcon}),e("h3",{children:"AniList Manga"}),P?null:p?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e($e,{}),p&&x!=="anilist"&&e("p",{style:{color:"var(--color-warning)",marginTop:"8px",fontSize:"0.85rem"},children:"Not the active tracker - sync disabled."}),p&&x==="anilist"&&e(g,{children:[e("hr",{className:a.divider}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"username",checked:Z==="username",onChange:()=>fe("username")}),e("span",{children:"Quick Import"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaMode",value:"sync",checked:Z==="sync",onChange:()=>fe("sync")}),e("span",{children:"Two-way Sync"})]})]}),Z==="username"?e(g,{children:[e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter AniList username",value:E,onChange:n=>ke(n.currentTarget.value),className:a.input,disabled:q.isPending,onKeyDown:n=>{n.key==="Enter"&&E.trim()&&q.mutate()}})}),e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:u,onChange:n=>_(n.currentTarget.checked),className:a.checkbox,disabled:q.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:a.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})})]}):e(g,{children:[e("p",{className:a.syncHint,children:"Merges chapter progress non-destructively: pushes manga and chapters you read on dango to AniList, and pulls anything you updated on AniList into dango. Local titles are linked only on exact title matches, and bookmarks with no chapters read are never pushed."}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"two-way",checked:ce==="two-way",onChange:()=>_e("two-way")}),e("span",{children:"Two-way"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"mangaDirection",value:"pull-only",checked:ce==="pull-only",onChange:()=>_e("pull-only")}),e("span",{children:"Pull only (never writes to AniList)"})]})]})]}),Z==="username"?e("button",{className:a.syncBtn,onClick:()=>q.mutate(),disabled:!E.trim()||q.isPending,children:[e(m,{name:"download"}),q.isPending?"Importing...":"Start Import"]}):e(g,{children:[e("button",{className:a.syncBtn,onClick:()=>ee.mutate(),disabled:ee.isPending,children:[e(m,{name:"sync-alt",className:ee.isPending?a.spin:""}),ee.isPending?"Syncing...":"Start Manga Sync"]}),w&&e(g,{children:[e("div",{className:a.syncSummary,children:["Pushed: ",w.pushed," · Pulled: ",w.pulled," · Merged: ",w.merged," · Unchanged:"," ",w.unchanged,(w.skipped??0)>0&&e("span",{children:[" · Skipped: ",w.skipped]}),w.errors.length>0&&e("span",{className:a.syncErrors,children:[" ","· ",w.errors.length," error",w.errors.length>1?"s":""]})]}),(w.warnings?.length??0)>0&&e("div",{className:a.syncErrors,style:{marginTop:"8px"},children:[(w.warnings??[]).slice(0,5).map((n,v)=>e("div",{children:["⚠ ",n]},v)),(w.warnings?.length??0)>5&&e("div",{children:["+",(w.warnings?.length??0)-5," more warning(s)"]})]})]})]})]})]})}),!h&&e(g,{children:e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"myanimelist",className:a.malIcon}),e("h3",{children:"MyAnimeList"}),P?null:M?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e(Ke,{active:x==="mal"}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"username",checked:G==="username",onChange:()=>je("username")}),e("span",{children:"Username"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMode",value:"xml",checked:G==="xml",onChange:()=>je("xml")}),e("span",{children:"XML File"})]})]}),G==="username"?e(g,{children:[e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:Q,onChange:n=>Se(n.currentTarget.value),className:a.input,disabled:z.isPending,onKeyDown:n=>{n.key==="Enter"&&Q.trim()&&z.mutate({erase:F,useOfflineDb:O,skipFallback:H})}})}),z.isPending&&e("div",{className:a.importLoading,children:[e(m,{name:"sync-alt",className:a.spin}),e("span",{children:"Importing from MAL..."})]})]}):e("div",{className:a.uploadArea,children:e("div",{className:a.fileInputWrapper,children:[e("input",{type:"file",id:"malFile",accept:".xml,application/xml",className:a.fileInput,onChange:We,disabled:K}),e("div",{className:a.fileDisplay,children:[e(m,{name:"file-alt",className:a.fileIcon}),e("span",{className:a.fileName,children:Me||"Choose XML file..."})]}),e("label",{htmlFor:"malFile",className:a.browseButton,children:"Browse"})]})}),e("div",{className:a.optionsArea,children:[e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:F,onChange:n=>Le(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Erase current watchlist"}),e("span",{className:a.optionDesc,children:"Delete existing watchlist before importing."})]})]}),e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:O,onChange:n=>He(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Use offline database (fast)"}),e("span",{className:a.optionDesc,children:"Match by MAL ID locally first - instant and avoids AniList rate limits."})]})]}),e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:H,onChange:n=>Ge(n.currentTarget.checked),className:a.checkbox,disabled:K||z.isPending}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Skip online fallback"}),e("span",{className:a.optionDesc,children:"Only import offline matches. Unmatched titles are skipped without API calls."})]})]})]}),G==="username"?e("button",{className:a.syncBtn,onClick:()=>z.mutate({erase:F,useOfflineDb:O,skipFallback:H}),disabled:!Q.trim()||z.isPending,children:[e(m,{name:"download"}),z.isPending?"Importing...":"Start Import"]}):e("div",{className:a.actions,children:K?e(ge,{onClick:Ye,className:a.cancelBtn,children:"Cancel Import"}):e(ge,{onClick:Xe,className:a.importBtn,disabled:!Me,children:[e(m,{name:"upload"})," Start Import"]})}),G==="username"&&z.isError&&e("div",{className:`${a.statusMessage} ${a.error}`,children:z.error.message}),K&&A&&e("div",{className:a.progressSection,children:[e("div",{className:a.progressBar,children:e("div",{className:a.progressFill,style:{width:`${Je}%`}})}),e("div",{className:a.progressInfo,children:[e("span",{className:a.progressCount,children:[A.current," / ",A.total]}),e("span",{className:a.progressTitle,children:A.found?e(g,{children:[A.matchedTitle,e("span",{className:`${a.sourceBadge} ${a[A.source||"anilist"]}`,children:A.source==="kitsu"?"Kitsu":A.source==="offline"?"Offline DB":"AniList"})]}):e("span",{className:a.skipped,children:["Skipped: ",A.title]})})]})]}),de&&e("div",{className:`${a.statusMessage} ${a.success}`,children:["Import complete! Imported: ",de.imported,", Skipped: ",de.skipped,"."]}),Pe&&e("div",{className:`${a.statusMessage} ${a.error}`,children:Pe})]})}),h&&e("div",{className:a.importCard,children:[e("div",{className:a.cardHeader,children:e("div",{className:a.cardTitleRow,children:[e(m,{name:"myanimelist",className:a.malIcon}),e("h3",{children:"MyAnimeList Manga"}),P?null:M?e("span",{className:a.badgeOnline,children:"Connected"}):e("span",{className:a.badgeOffline,children:"Not connected"})]})}),e(Ke,{kind:"manga",active:x==="mal"}),e("div",{className:a.radioGroup,children:[e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"username",checked:ae==="username",onChange:()=>ve("username")}),e("span",{children:"Username"})]}),e("label",{className:a.radioLabel,children:[e("input",{type:"radio",name:"malMangaMode",value:"xml",checked:ae==="xml",onChange:()=>ve("xml")}),e("span",{children:"XML File"})]})]}),ae==="username"?e("div",{className:a.inputGroup,children:e("input",{type:"text",placeholder:"Enter MAL username",value:U,onChange:n=>be(n.currentTarget.value),className:a.input,disabled:j.isPending,onKeyDown:n=>{n.key==="Enter"&&U.trim()&&j.mutate()}})}):e("div",{className:a.uploadArea,children:e("div",{className:a.fileInputWrapper,children:[e("input",{type:"file",id:"malMangaFile",accept:".xml,application/xml",className:a.fileInput,onChange:n=>Qe(n.currentTarget.files?.[0]?.name??""),disabled:ne}),e("div",{className:a.fileDisplay,children:[e(m,{name:"file-alt",className:a.fileIcon}),e("span",{className:a.fileName,children:Ie||"Choose XML file..."})]}),e("label",{htmlFor:"malMangaFile",className:a.browseButton,children:"Browse"})]})}),e("div",{className:a.optionsArea,children:e("label",{className:a.checkboxLabel,children:[e("input",{type:"checkbox",checked:u,onChange:n=>_(n.currentTarget.checked),className:a.checkbox,disabled:j.isPending||ne}),e("span",{className:a.checkboxCustom}),e("div",{className:a.optionText,children:[e("span",{className:a.optionTitle,children:"Replace AniList-linked manga"}),e("span",{className:a.optionDesc,children:"Clears previously imported (anilist:) entries before importing. Your provider bookmarks are never touched."})]})]})}),ae==="username"?e("button",{className:a.syncBtn,onClick:()=>j.mutate(),disabled:!U.trim()||j.isPending,children:[e(m,{name:"download"}),j.isPending?"Importing...":"Start Import"]}):e("div",{className:a.actions,children:e(ge,{onClick:Oe,className:a.importBtn,disabled:ne||!Ie,children:[e(m,{name:"upload"})," ",ne?"Importing...":"Start Import"]})}),j.isError&&e("div",{className:`${a.statusMessage} ${a.error}`,children:j.error.message}),Ce&&e("div",{className:`${a.statusMessage} ${a.error}`,children:Ce}),oe&&e("div",{className:`${a.statusMessage} ${a.success}`,children:["Import complete! Imported: ",oe.imported,", Skipped:"," ",oe.skipped,"."]}),e("p",{style:{fontSize:"0.75rem",color:"var(--text-tertiary)",marginTop:"8px"},children:"MAL manga is matched to AniList by MAL ID with a title fallback. Unmatched titles are skipped. Imports land as AniList-linked entries alongside your provider bookmarks."})]})]})};export{In as default};
@@ -1,4 +1,4 @@
1
- import{u as t,d as g,A as O,h as p,S as Xe,g as ts,q as E,o as ns,p as rs,a as ss,T as Se}from"./vendor-core-DfaOB3Rn.js";import{g as Un,p as D,t as pt,a6 as os,a2 as as,O as On,e as is,a9 as ls,F as mr,B as cn}from"./index-BR99iwWT.js";import{P as cs,a as us,b as ds,F as ms,f as bs,c as hs}from"./PlayerProvider-DjIXyFBk.js";import{u as fs}from"./vendor-query-BBT5_sHx.js";import{I as be}from"./vendor-icons-DrybRNxP.js";import{p as Hn,M as vs,z as vr,f as Wn,c as ps,C as gs,a as ys,P as Ss,b as un,u as _s,i as Ts,j as Cs,n as ks,h as Es,k as Ns,m as Is,l as As,s as Vn,d as xs,e as ws,g as Bs,r as Ls,o as xe,A as Ps,t as Ms,E as Rs,w as zs,x as $s,v as ae,y as Ds,R as Os,q as Vs}from"./useWatchAlongPlayer-hjLY2hHu.js";import{S as Fs,O as Fn,a as qs,A as Us,b as Hs}from"./OptionListMenu-CFBJv5e-.js";import{M as Ws}from"./MatureConsentModal-BTJloHUV.js";import{u as Ks}from"./useProviders-DVv7j4AK.js";import{e as Ys,f as js,g as Gs,d as Qs,c as Xs,h as Zs,i as Js}from"./useTvLibrary-DnKiDhxZ.js";import{l as eo,s as to,i as dn,h as br}from"./playbackCompletion-C8izYMOL.js";import{u as no}from"./useIsMobile-Dvx1uJ82.js";import{S as ro}from"./SynopsisText-B3Sa5pRv.js";import{W as so}from"./WatchAlongPanel-DTjl8tog.js";import"./libraryInvalidation-BirscVrS.js";const oo="_fullscreenFlat_10bzs_1",ao="_timeDisplay_10bzs_12",io="_bottomControls_10bzs_16",lo="_leftControls_10bzs_20",co="_rightControls_10bzs_21",uo="_controlBtn_10bzs_25",mo="_controlsOverlay_10bzs_32",bo="_hidden_10bzs_52",ho="_topControls_10bzs_58",fo="_backBtn_10bzs_78",vo="_videoTitleInfo_10bzs_98",po="_animeTitle_10bzs_104",go="_episodeLabel_10bzs_112",yo="_speedBoostBadge_10bzs_119",So="_progressBarContainer_10bzs_165",_o="_progressBar_10bzs_165",To="_thumb_10bzs_184",Co="_bufferedBar_10bzs_202",ko="_watchedBar_10bzs_212",Eo="_scrubbing_10bzs_237",No="_timeBubble_10bzs_241",Io="_bottomControlsRow_10bzs_255",Ao="_nextEpisodeBtn_10bzs_278",xo="_active_10bzs_340",wo="_settingsPanel_10bzs_352",Bo="_settingsHeader_10bzs_371",Lo="_settingsBackBtn_10bzs_379",Po="_settingsTitle_10bzs_397",Mo="_settingsContent_10bzs_408",Ro="_currentValue_10bzs_417",zo="_menuItem_10bzs_423",$o="_menuNote_10bzs_456",Do="_loadingOverlay_10bzs_465",Oo="_loadingDots_10bzs_476",Vo="_dot_10bzs_481",Fo="_bufferingOverlay_10bzs_510",qo="_bufferingSpinner_10bzs_519",o={fullscreenFlat:oo,timeDisplay:ao,bottomControls:io,leftControls:lo,rightControls:co,controlBtn:uo,controlsOverlay:mo,hidden:bo,topControls:ho,backBtn:fo,videoTitleInfo:vo,animeTitle:po,episodeLabel:go,speedBoostBadge:yo,progressBarContainer:So,progressBar:_o,thumb:To,bufferedBar:Co,watchedBar:ko,scrubbing:Eo,timeBubble:No,bottomControlsRow:Io,nextEpisodeBtn:Ao,active:xo,settingsPanel:wo,settingsHeader:Bo,settingsBackBtn:Lo,settingsTitle:Po,settingsContent:Mo,currentValue:Ro,menuItem:zo,menuNote:$o,loadingOverlay:Do,loadingDots:Oo,dot:Vo,bufferingOverlay:Fo,bufferingSpinner:qo},Uo=({player:s,visible:h,settingsOpen:z,onOpenSettings:B,onCloseSettings:M,hasSubtitles:T,isSubtitleActive:N,subtitles:u,onSubtitleChange:i,showNextEpisodeButton:S,onNextEpisode:r,isTheaterMode:L,onTheaterModeToggle:he,timeLabelRef:X})=>{const{state:m,actions:ke}=s,we=()=>{if(N){i(-1);return}let fe=null;try{fe=D.getItem("tvLastSubtitle")}catch{}i(Hn(u,{lastKey:fe,enabled:!0}))};return t("div",{className:`${o.controlsOverlay} ${h?"":o.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:o.bottomControls,onClick:fe=>fe.stopPropagation(),children:[t(cs,{classes:{container:o.progressBarContainer,scrubbing:o.scrubbing,timeBubble:o.timeBubble,bar:o.progressBar,buffered:o.bufferedBar,watched:o.watchedBar,thumb:o.thumb},timeLabelRef:X}),t("div",{className:o.bottomControlsRow,children:[t("div",{className:o.leftControls,children:[t(us,{className:o.controlBtn}),t(ds,{buttonClassName:o.controlBtn,onExpandedChange:ke.setShowVolumeSlider}),t("span",{className:o.timeDisplay,ref:X,children:[Un(0)," / ",Un(m.duration)]})]}),t("div",{className:o.rightControls,children:[S&&t("button",{className:o.nextEpisodeBtn,onClick:r,title:"Play next episode",children:"Next EP"}),T&&t("button",{className:`${o.controlBtn} ${N?o.active:""}`,onClick:we,"aria-label":N?"Turn subtitles off":"Turn subtitles on",children:t(be,{name:"closed-captioning"})}),t("button",{className:`${o.controlBtn} ${z?o.active:""}`,onClick:()=>z?M():B(),"aria-label":"Settings",children:t(be,{name:"cog"})}),t("button",{className:`${o.controlBtn} ${L?o.active:""}`,onClick:fe=>{fe.stopPropagation(),he()},title:L?"Exit Theater Mode":"Theater Mode","aria-label":L?"Exit Theater Mode":"Theater Mode",children:t(be,{name:"tv"})}),t(ms,{className:o.controlBtn})]})]})]})})},mn=-6e4,qn=6e4,hr=500,Ho=({classes:s,delayMs:h,onDelayChange:z})=>{const[B,M]=g(null),T=B??h,N=O(z);N.current=z;const u=O(h);u.current=h;const i=O(null);i.current=B,p(()=>{M(null)},[h]),p(()=>()=>{const L=i.current;L!==null&&L!==u.current&&N.current(L)},[]);const S=L=>{u.current=L,i.current=null,N.current(L),M(null)},r=L=>{const he=i.current??u.current,X=Math.max(mn,Math.min(qn,he+L));S(X)};return t(Xe,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:s.item,onClick:()=>r(-hr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>r(hr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>S(0),disabled:T===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(vs,{label:"Subtitle timing",display:vr(T),min:mn,max:qn,step:100,value:T,percent:(T-mn)/(qn-mn)*100,onChange:L=>{const he=Math.round(L);i.current=he,M(he)},onCommit:()=>{const L=i.current;L!==null&&S(L)}}),t("div",{className:s.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},Wo=({view:s,onSelectView:h,onClose:z,player:B,onSubtitleStyleChange:M,streams:T,resolutionIdx:N,onResolutionChange:u,hasSubtitles:i,subtitles:S,selectedSubtitle:r,isSubtitleActive:L,onSubtitleChange:he,audioTracks:X,selectedAudioTrack:m,onAudioTrackChange:ke,videoDelayEnabled:we,onVideoDelayToggle:fe,videoDelayMs:ve,onVideoDelayChange:_,onCalibrate:gt,subtitleDelayMs:Ze,onSubtitleDelayChange:C,ambientSettings:H,onAmbientChange:W})=>{const{state:ie}=B,yt=()=>t(Xe,{children:[T.length>1&&t("button",{className:o.menuItem,onClick:()=>h("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:o.currentValue,children:T[N]?.quality||"Auto"})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:o.currentValue,children:L?S[r]?.label||S[r]?.language:"Off"})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:o.currentValue,children:[ie.subtitleFontSize.toFixed(1),"x · ",ie.subtitlePosition]})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:o.currentValue,children:vr(Ze)})]}),X.length>0&&t("button",{className:o.menuItem,onClick:()=>h("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:o.currentValue,children:X[m]?.label||X[m]?.language})]}),t("button",{className:o.menuItem,onClick:()=>h("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:o.currentValue,children:we?`${ve}ms`:"Off"})]}),H&&W&&t("button",{className:o.menuItem,onClick:()=>h("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:o.currentValue,children:H.enabled?"On":"Off"})]})]}),Be=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:T.map((A,re)=>({key:String(re),label:A.quality,selected:re===N})),onSelect:A=>u(Number(A))}),Je=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:[{key:"off",label:"Off",selected:!L},...S.map((A,re)=>({key:String(re),label:A.label||A.language,selected:re===r}))],onSelect:A=>he(A==="off"?-1:Number(A))}),ee=()=>t(qs,{classes:{item:o.menuItem,active:o.active},values:{fontSize:ie.subtitleFontSize,position:ie.subtitlePosition,bgOpacity:ie.subtitleBgOpacity,bgColor:ie.subtitleBgColor,textColor:ie.subtitleTextColor,edge:ie.subtitleEdge,bold:ie.subtitleBold},onChange:M}),St=()=>t(Ho,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},delayMs:Ze,onDelayChange:A=>C?.(A)}),st=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:X.map((A,re)=>({key:String(re),label:A.label||A.language,selected:re===m})),onSelect:A=>ke(Number(A))}),Le=()=>t(Us,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},enabled:we,delayMs:ve,onToggle:A=>fe?.(A),onDelayChange:A=>_?.(A),onCalibrate:gt}),G=()=>H&&W?t(Hs,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},values:H,onChange:W}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:A=>A.stopPropagation(),children:t(Fs,{classes:{panel:o.settingsPanel,header:o.settingsHeader,backBtn:o.settingsBackBtn,title:o.settingsTitle,content:o.settingsContent},title:s==="main"?"Settings":s==="subtitle-style"?"Subtitle Style":s==="subtitle-timing"?"Subtitle Timing":s==="audio"?"Audio Track":s==="resolution"?"Resolution":s==="av-sync"?"A/V Sync":s==="ambient"?"Ambient Light":s.charAt(0).toUpperCase()+s.slice(1),onBack:()=>s==="main"?z():h("main"),children:[s==="main"&&yt(),s==="resolution"&&Be(),s==="subtitles"&&Je(),s==="subtitle-style"&&ee(),s==="subtitle-timing"&&St(),s==="audio"&&st(),s==="av-sync"&&Le(),s==="ambient"&&G()]})})},Ko=({player:s,title:h,episodeLabel:z,server:B,audioTracks:M,selectedAudioTrack:T,onAudioTrackChange:N,subtitles:u,selectedSubtitle:i,onSubtitleChange:S,streams:r,resolutionIdx:L,onResolutionChange:he,onBack:X,children:m,videoDelayEnabled:ke=!1,onVideoDelayToggle:we,videoDelayMs:fe=0,onVideoDelayChange:ve,onCalibrateAvSync:_,subtitleDelayMs:gt=0,onSubtitleDelayChange:Ze,showNextEpisodeButton:C=!1,onNextEpisode:H,isLoading:W=!1,isTheaterMode:ie,onTheaterModeToggle:yt,ambientSettings:Be,onAmbientChange:Je})=>{const{state:ee,refs:St,actions:st}=s,Le=St.videoRef,{subtitleFontSize:G,subtitlePosition:A,subtitleBgOpacity:re,subtitleBgColor:le,subtitleTextColor:Pe,subtitleEdge:Me,subtitleBold:te}=ee,[Fe,et]=g(null),qe=O(null),[ot,Ee]=g(0);p(()=>{const oe=Le.current;if(!oe)return;const _e=()=>Ee(oe.clientHeight||0);_e();const pe=new ResizeObserver(_e);return pe.observe(oe),()=>pe.disconnect()},[Le]);const _t=st.setSubtitleStyle;p(()=>{const oe="tv-player-subtitle-style";let _e=document.getElementById(oe);_e||(_e=document.createElement("style"),_e.id=oe,document.head.appendChild(_e));const pe={fontSize:G,position:A,bgOpacity:re,bgColor:le,textColor:Pe,edge:Me,bold:te},Z=Le.current,Ot=Wn(G,ot||Z?.clientHeight||720);if(_e.textContent=ps({...pe,fontSize:Ot}),Z){const lt=()=>{const w=Number(A);return isNaN(w)?0:Math.max(0,Math.min(100,w))},ct=(w,c)=>{try{const l=w;l.snapToLines=!1,l.line=c}catch{}},kt=()=>{const w=Ot*16,c=Z.videoHeight||Z.clientHeight||720,l=Z.videoWidth||Z.clientWidth||1280;return{step:w*1.3/c*100,chars:Math.max(20,Math.floor(l/(w*.55)))}},ce=w=>{const c=Math.max(0,Math.min(100,100-lt())),l=Array.from(w.activeCues??[]);if(l.length<=1){l.forEach($e=>ct($e,c));return}const{step:ue,chars:de}=kt();let xt=c;for(let $e=l.length-1;$e>=0;$e--){const wt=String(l[$e].text??"").replace(/<[^>]*>/g,"").split(`
1
+ import{u as t,d as g,A as O,h as p,S as Xe,g as ts,q as E,o as ns,p as rs,a as ss,T as Se}from"./vendor-core-DfaOB3Rn.js";import{g as Un,p as D,t as pt,a6 as os,a2 as as,O as On,e as is,a9 as ls,F as mr,B as cn}from"./index-fS4AGBy2.js";import{P as cs,a as us,b as ds,F as ms,f as bs,c as hs}from"./PlayerProvider-WO2tWEb1.js";import{u as fs}from"./vendor-query-BBT5_sHx.js";import{I as be}from"./vendor-icons-DrybRNxP.js";import{p as Hn,M as vs,z as vr,f as Wn,c as ps,C as gs,a as ys,P as Ss,b as un,u as _s,i as Ts,j as Cs,n as ks,h as Es,k as Ns,m as Is,l as As,s as Vn,d as xs,e as ws,g as Bs,r as Ls,o as xe,A as Ps,t as Ms,E as Rs,w as zs,x as $s,v as ae,y as Ds,R as Os,q as Vs}from"./useWatchAlongPlayer-DC-nsje5.js";import{S as Fs,O as Fn,a as qs,A as Us,b as Hs}from"./OptionListMenu-oRSmXUYN.js";import{M as Ws}from"./MatureConsentModal-J7mF0tSH.js";import{u as Ks}from"./useProviders-SXQCnsGW.js";import{e as Ys,f as js,g as Gs,d as Qs,c as Xs,h as Zs,i as Js}from"./useTvLibrary-D6KqZu5s.js";import{l as eo,s as to,i as dn,h as br}from"./playbackCompletion-Dfy-xXLg.js";import{u as no}from"./useIsMobile-Dvx1uJ82.js";import{S as ro}from"./SynopsisText-B3Sa5pRv.js";import{W as so}from"./WatchAlongPanel-CdJRfBiU.js";import"./libraryInvalidation-C4kz8swK.js";const oo="_fullscreenFlat_10bzs_1",ao="_timeDisplay_10bzs_12",io="_bottomControls_10bzs_16",lo="_leftControls_10bzs_20",co="_rightControls_10bzs_21",uo="_controlBtn_10bzs_25",mo="_controlsOverlay_10bzs_32",bo="_hidden_10bzs_52",ho="_topControls_10bzs_58",fo="_backBtn_10bzs_78",vo="_videoTitleInfo_10bzs_98",po="_animeTitle_10bzs_104",go="_episodeLabel_10bzs_112",yo="_speedBoostBadge_10bzs_119",So="_progressBarContainer_10bzs_165",_o="_progressBar_10bzs_165",To="_thumb_10bzs_184",Co="_bufferedBar_10bzs_202",ko="_watchedBar_10bzs_212",Eo="_scrubbing_10bzs_237",No="_timeBubble_10bzs_241",Io="_bottomControlsRow_10bzs_255",Ao="_nextEpisodeBtn_10bzs_278",xo="_active_10bzs_340",wo="_settingsPanel_10bzs_352",Bo="_settingsHeader_10bzs_371",Lo="_settingsBackBtn_10bzs_379",Po="_settingsTitle_10bzs_397",Mo="_settingsContent_10bzs_408",Ro="_currentValue_10bzs_417",zo="_menuItem_10bzs_423",$o="_menuNote_10bzs_456",Do="_loadingOverlay_10bzs_465",Oo="_loadingDots_10bzs_476",Vo="_dot_10bzs_481",Fo="_bufferingOverlay_10bzs_510",qo="_bufferingSpinner_10bzs_519",o={fullscreenFlat:oo,timeDisplay:ao,bottomControls:io,leftControls:lo,rightControls:co,controlBtn:uo,controlsOverlay:mo,hidden:bo,topControls:ho,backBtn:fo,videoTitleInfo:vo,animeTitle:po,episodeLabel:go,speedBoostBadge:yo,progressBarContainer:So,progressBar:_o,thumb:To,bufferedBar:Co,watchedBar:ko,scrubbing:Eo,timeBubble:No,bottomControlsRow:Io,nextEpisodeBtn:Ao,active:xo,settingsPanel:wo,settingsHeader:Bo,settingsBackBtn:Lo,settingsTitle:Po,settingsContent:Mo,currentValue:Ro,menuItem:zo,menuNote:$o,loadingOverlay:Do,loadingDots:Oo,dot:Vo,bufferingOverlay:Fo,bufferingSpinner:qo},Uo=({player:s,visible:h,settingsOpen:z,onOpenSettings:B,onCloseSettings:M,hasSubtitles:T,isSubtitleActive:N,subtitles:u,onSubtitleChange:i,showNextEpisodeButton:S,onNextEpisode:r,isTheaterMode:L,onTheaterModeToggle:he,timeLabelRef:X})=>{const{state:m,actions:ke}=s,we=()=>{if(N){i(-1);return}let fe=null;try{fe=D.getItem("tvLastSubtitle")}catch{}i(Hn(u,{lastKey:fe,enabled:!0}))};return t("div",{className:`${o.controlsOverlay} ${h?"":o.hidden}`,"data-speed-boost-ignore":"true",style:{pointerEvents:"none",background:"none",justifyContent:"flex-end"},children:t("div",{className:o.bottomControls,onClick:fe=>fe.stopPropagation(),children:[t(cs,{classes:{container:o.progressBarContainer,scrubbing:o.scrubbing,timeBubble:o.timeBubble,bar:o.progressBar,buffered:o.bufferedBar,watched:o.watchedBar,thumb:o.thumb},timeLabelRef:X}),t("div",{className:o.bottomControlsRow,children:[t("div",{className:o.leftControls,children:[t(us,{className:o.controlBtn}),t(ds,{buttonClassName:o.controlBtn,onExpandedChange:ke.setShowVolumeSlider}),t("span",{className:o.timeDisplay,ref:X,children:[Un(0)," / ",Un(m.duration)]})]}),t("div",{className:o.rightControls,children:[S&&t("button",{className:o.nextEpisodeBtn,onClick:r,title:"Play next episode",children:"Next EP"}),T&&t("button",{className:`${o.controlBtn} ${N?o.active:""}`,onClick:we,"aria-label":N?"Turn subtitles off":"Turn subtitles on",children:t(be,{name:"closed-captioning"})}),t("button",{className:`${o.controlBtn} ${z?o.active:""}`,onClick:()=>z?M():B(),"aria-label":"Settings",children:t(be,{name:"cog"})}),t("button",{className:`${o.controlBtn} ${L?o.active:""}`,onClick:fe=>{fe.stopPropagation(),he()},title:L?"Exit Theater Mode":"Theater Mode","aria-label":L?"Exit Theater Mode":"Theater Mode",children:t(be,{name:"tv"})}),t(ms,{className:o.controlBtn})]})]})]})})},mn=-6e4,qn=6e4,hr=500,Ho=({classes:s,delayMs:h,onDelayChange:z})=>{const[B,M]=g(null),T=B??h,N=O(z);N.current=z;const u=O(h);u.current=h;const i=O(null);i.current=B,p(()=>{M(null)},[h]),p(()=>()=>{const L=i.current;L!==null&&L!==u.current&&N.current(L)},[]);const S=L=>{u.current=L,i.current=null,N.current(L),M(null)},r=L=>{const he=i.current??u.current,X=Math.max(mn,Math.min(qn,he+L));S(X)};return t(Xe,{children:[t("div",{style:{display:"flex",gap:6,padding:"0.5rem 0.75rem 0.25rem"},children:[t("button",{type:"button",className:s.item,onClick:()=>r(-hr),"aria-label":"Show subtitles 0.5 seconds earlier",style:{flex:1,justifyContent:"center"},children:t("span",{children:"-0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>r(hr),"aria-label":"Show subtitles 0.5 seconds later",style:{flex:1,justifyContent:"center"},children:t("span",{children:"+0.5s"})}),t("button",{type:"button",className:s.item,onClick:()=>S(0),disabled:T===0,"aria-label":"Reset subtitle timing",style:{flex:1,justifyContent:"center"},children:t("span",{children:"Reset"})})]}),t(vs,{label:"Subtitle timing",display:vr(T),min:mn,max:qn,step:100,value:T,percent:(T-mn)/(qn-mn)*100,onChange:L=>{const he=Math.round(L);i.current=he,M(he)},onCommit:()=>{const L=i.current;L!==null&&S(L)}}),t("div",{className:s.note,children:"Positive delays subtitles (show later). Negative shows them earlier. 0.0s is default."})]})},Wo=({view:s,onSelectView:h,onClose:z,player:B,onSubtitleStyleChange:M,streams:T,resolutionIdx:N,onResolutionChange:u,hasSubtitles:i,subtitles:S,selectedSubtitle:r,isSubtitleActive:L,onSubtitleChange:he,audioTracks:X,selectedAudioTrack:m,onAudioTrackChange:ke,videoDelayEnabled:we,onVideoDelayToggle:fe,videoDelayMs:ve,onVideoDelayChange:_,onCalibrate:gt,subtitleDelayMs:Ze,onSubtitleDelayChange:C,ambientSettings:H,onAmbientChange:W})=>{const{state:ie}=B,yt=()=>t(Xe,{children:[T.length>1&&t("button",{className:o.menuItem,onClick:()=>h("resolution"),children:[t("span",{children:"Resolution"}),t("span",{className:o.currentValue,children:T[N]?.quality||"Auto"})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitles"),children:[t("span",{children:"Subtitles"}),t("span",{className:o.currentValue,children:L?S[r]?.label||S[r]?.language:"Off"})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitle-style"),children:[t("span",{children:"Subtitle Style"}),t("span",{className:o.currentValue,children:[ie.subtitleFontSize.toFixed(1),"x · ",ie.subtitlePosition]})]}),i&&t("button",{className:o.menuItem,onClick:()=>h("subtitle-timing"),children:[t("span",{children:"Subtitle Timing"}),t("span",{className:o.currentValue,children:vr(Ze)})]}),X.length>0&&t("button",{className:o.menuItem,onClick:()=>h("audio"),children:[t("span",{children:"Audio Track"}),t("span",{className:o.currentValue,children:X[m]?.label||X[m]?.language})]}),t("button",{className:o.menuItem,onClick:()=>h("av-sync"),children:[t("span",{children:"A/V Sync"}),t("span",{className:o.currentValue,children:we?`${ve}ms`:"Off"})]}),H&&W&&t("button",{className:o.menuItem,onClick:()=>h("ambient"),children:[t("span",{children:"Ambient Light"}),t("span",{className:o.currentValue,children:H.enabled?"On":"Off"})]})]}),Be=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:T.map((A,re)=>({key:String(re),label:A.quality,selected:re===N})),onSelect:A=>u(Number(A))}),Je=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:[{key:"off",label:"Off",selected:!L},...S.map((A,re)=>({key:String(re),label:A.label||A.language,selected:re===r}))],onSelect:A=>he(A==="off"?-1:Number(A))}),ee=()=>t(qs,{classes:{item:o.menuItem,active:o.active},values:{fontSize:ie.subtitleFontSize,position:ie.subtitlePosition,bgOpacity:ie.subtitleBgOpacity,bgColor:ie.subtitleBgColor,textColor:ie.subtitleTextColor,edge:ie.subtitleEdge,bold:ie.subtitleBold},onChange:M}),St=()=>t(Ho,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},delayMs:Ze,onDelayChange:A=>C?.(A)}),st=()=>t(Fn,{classes:{item:o.menuItem,active:o.active},options:X.map((A,re)=>({key:String(re),label:A.label||A.language,selected:re===m})),onSelect:A=>ke(Number(A))}),Le=()=>t(Us,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},enabled:we,delayMs:ve,onToggle:A=>fe?.(A),onDelayChange:A=>_?.(A),onCalibrate:gt}),G=()=>H&&W?t(Hs,{classes:{item:o.menuItem,active:o.active,note:o.menuNote},values:H,onChange:W}):null;return t("div",{"data-speed-boost-ignore":"true",onClick:A=>A.stopPropagation(),children:t(Fs,{classes:{panel:o.settingsPanel,header:o.settingsHeader,backBtn:o.settingsBackBtn,title:o.settingsTitle,content:o.settingsContent},title:s==="main"?"Settings":s==="subtitle-style"?"Subtitle Style":s==="subtitle-timing"?"Subtitle Timing":s==="audio"?"Audio Track":s==="resolution"?"Resolution":s==="av-sync"?"A/V Sync":s==="ambient"?"Ambient Light":s.charAt(0).toUpperCase()+s.slice(1),onBack:()=>s==="main"?z():h("main"),children:[s==="main"&&yt(),s==="resolution"&&Be(),s==="subtitles"&&Je(),s==="subtitle-style"&&ee(),s==="subtitle-timing"&&St(),s==="audio"&&st(),s==="av-sync"&&Le(),s==="ambient"&&G()]})})},Ko=({player:s,title:h,episodeLabel:z,server:B,audioTracks:M,selectedAudioTrack:T,onAudioTrackChange:N,subtitles:u,selectedSubtitle:i,onSubtitleChange:S,streams:r,resolutionIdx:L,onResolutionChange:he,onBack:X,children:m,videoDelayEnabled:ke=!1,onVideoDelayToggle:we,videoDelayMs:fe=0,onVideoDelayChange:ve,onCalibrateAvSync:_,subtitleDelayMs:gt=0,onSubtitleDelayChange:Ze,showNextEpisodeButton:C=!1,onNextEpisode:H,isLoading:W=!1,isTheaterMode:ie,onTheaterModeToggle:yt,ambientSettings:Be,onAmbientChange:Je})=>{const{state:ee,refs:St,actions:st}=s,Le=St.videoRef,{subtitleFontSize:G,subtitlePosition:A,subtitleBgOpacity:re,subtitleBgColor:le,subtitleTextColor:Pe,subtitleEdge:Me,subtitleBold:te}=ee,[Fe,et]=g(null),qe=O(null),[ot,Ee]=g(0);p(()=>{const oe=Le.current;if(!oe)return;const _e=()=>Ee(oe.clientHeight||0);_e();const pe=new ResizeObserver(_e);return pe.observe(oe),()=>pe.disconnect()},[Le]);const _t=st.setSubtitleStyle;p(()=>{const oe="tv-player-subtitle-style";let _e=document.getElementById(oe);_e||(_e=document.createElement("style"),_e.id=oe,document.head.appendChild(_e));const pe={fontSize:G,position:A,bgOpacity:re,bgColor:le,textColor:Pe,edge:Me,bold:te},Z=Le.current,Ot=Wn(G,ot||Z?.clientHeight||720);if(_e.textContent=ps({...pe,fontSize:Ot}),Z){const lt=()=>{const w=Number(A);return isNaN(w)?0:Math.max(0,Math.min(100,w))},ct=(w,c)=>{try{const l=w;l.snapToLines=!1,l.line=c}catch{}},kt=()=>{const w=Ot*16,c=Z.videoHeight||Z.clientHeight||720,l=Z.videoWidth||Z.clientWidth||1280;return{step:w*1.3/c*100,chars:Math.max(20,Math.floor(l/(w*.55)))}},ce=w=>{const c=Math.max(0,Math.min(100,100-lt())),l=Array.from(w.activeCues??[]);if(l.length<=1){l.forEach($e=>ct($e,c));return}const{step:ue,chars:de}=kt();let xt=c;for(let $e=l.length-1;$e>=0;$e--){const wt=String(l[$e].text??"").replace(/<[^>]*>/g,"").split(`
2
2
  `).reduce((Ft,fn)=>Ft+Math.max(1,Math.ceil(fn.length/de)),0),Vt=xt-wt*ue;ct(l[$e],Math.max(0,Vt)),xt=Vt-ue*.4}},Et=()=>{const w=Math.max(0,Math.min(100,100-lt()));Array.from(Z.textTracks).forEach(c=>{c.cues&&(Array.from(c.cues).forEach(l=>ct(l,w)),c.mode==="showing"&&ce(c))})};Et();const Te=w=>{const c=w.target;c.mode==="showing"&&ce(c)},Nt=()=>{Array.from(Z.textTracks).forEach(w=>{w.removeEventListener("cuechange",Te),w.addEventListener("cuechange",Te)}),Et()};Array.from(Z.textTracks).forEach(w=>{w.addEventListener("cuechange",Te)}),Z.textTracks.addEventListener("addtrack",Nt);const It=Array.from(Z.querySelectorAll("track")),At=()=>Et();return It.forEach(w=>w.addEventListener("load",At)),()=>{Array.from(Z.textTracks).forEach(w=>{w.removeEventListener("cuechange",Te)}),Z.textTracks.removeEventListener("addtrack",Nt),It.forEach(w=>w.removeEventListener("load",At))}}},[G,A,re,le,Pe,Me,te,i,u,Le,ot]);const se=u.length>0,Re=i>=0,ze=()=>{et("main"),st.setShowControls(!0)},Ue=()=>{et(null)},tt=ee.showControls||!!Fe,Tt=bs(s.engine),at=Tt.audioTracks.find(oe=>oe.id===Tt.activeAudioTrack)??M[T],He=i>=0?u[i]??Tt.subtitleTracks.find(oe=>oe.id===i):void 0,bn=t(gs,{visible:tt,title:h,episode:z,server:W?void 0:B,audio:W?void 0:at?.label||at?.language,subtitles:W?void 0:He?.label||He?.language,onBack:X,classes:{overlay:o.controlsOverlay,hidden:o.hidden,top:o.topControls,backBtn:o.backBtn,titleInfo:o.videoTitleInfo,title:o.animeTitle,episode:o.episodeLabel}}),Ct=!W&&!ee.isBuffering&&ee.duration>0?t(ys,{}):null,K=t(Uo,{player:s,visible:tt,settingsOpen:!!Fe,onOpenSettings:ze,onCloseSettings:Ue,hasSubtitles:se,isSubtitleActive:Re,subtitles:u,onSubtitleChange:S,showNextEpisodeButton:C,onNextEpisode:H,isTheaterMode:ie,onTheaterModeToggle:yt,timeLabelRef:qe}),it=Fe?t(Wo,{view:Fe,onSelectView:et,onClose:Ue,player:s,onSubtitleStyleChange:_t,streams:r,resolutionIdx:L,onResolutionChange:he,hasSubtitles:se,subtitles:u,selectedSubtitle:i,isSubtitleActive:Re,onSubtitleChange:S,audioTracks:M,selectedAudioTrack:T,onAudioTrackChange:N,videoDelayEnabled:ke,onVideoDelayToggle:we,videoDelayMs:fe,onVideoDelayChange:ve,onCalibrate:()=>{et(null),_?.()},subtitleDelayMs:gt,onSubtitleDelayChange:Ze,ambientSettings:Be,onAmbientChange:Je}):null,x=t(Xe,{children:[W&&t("div",{className:o.loadingOverlay,"aria-hidden":"true",children:t("div",{className:o.loadingDots,children:[t("div",{className:o.dot}),t("div",{className:o.dot}),t("div",{className:o.dot})]})}),ee.isBuffering&&!W&&t("div",{className:o.bufferingOverlay,"aria-hidden":"true",children:t("div",{className:o.bufferingSpinner})}),ee.isSpeedBoostActive&&t("div",{className:o.speedBoostBadge,"aria-hidden":"true",children:[t("span",{children:"2x"}),t(be,{name:"forward",size:12})]})]});return t(Ss,{engine:s.engine,topBar:bn,centerControls:Ct,bottomBar:!W&&ee.duration>0?K:null,settingsPanel:it,overlays:x,isInteracting:!!Fe||ee.showVolumeSlider,nativeControls:ee.useNativeControls,onStageClick:Ue,className:ee.isFullscreen?o.fullscreenFlat:"",children:m})},Yo=({servers:s,selectedServer:h,onServerSelect:z})=>s.length===0?null:t("div",{className:un.sourceSelectionContainer,children:[t("h4",{children:"Source"}),t("div",{className:un.sourceButtons,children:s.map(B=>t("button",{className:`${un.sourceButton} ${h===B?un.active:""}`,onClick:()=>z(B),children:B},B))})]}),jo=ts.memo(Yo);function Go({details:s,isMovie:h,season:z,episode:B,videoRef:M,active:T}){const N=O("");N.current||(N.current=`tv-${Date.now()}-${Math.random().toString(36).slice(2)}`);const u=E(()=>{if(!s)return;const i=M.current,S=h?"":`S${String(z).padStart(2,"0")}E${String(B).padStart(2,"0")}`;pt.discord.tvPresence.mutate({title:s.title,episodeLabel:S,isPlaying:i?!i.paused&&!i.ended:!0,thumbnail:s.poster,currentTime:i?i.currentTime:0,duration:i&&i.duration||0,isAdult:s.adult===!0,sessionId:N.current}).catch(()=>{}),pt.discord.heartbeat.mutate({sessionId:N.current}).catch(()=>{})},[s,h,z,B,M]);return p(()=>{if(!s)return;u();const i=window.setInterval(()=>{const S=M.current;(!S||!S.paused)&&u()},15e3);return()=>window.clearInterval(i)},[u,s,M]),p(()=>{if(!s||!T)return;const i=M.current;if(!i)return;const S=()=>u();return i.addEventListener("play",S),i.addEventListener("pause",S),i.addEventListener("seeked",S),()=>{i.removeEventListener("play",S),i.removeEventListener("pause",S),i.removeEventListener("seeked",S)}},[s,T,u,M]),p(()=>{const i=N.current,S=()=>os(i),r=()=>S();return window.addEventListener("pagehide",r),window.addEventListener("beforeunload",r),()=>{window.removeEventListener("pagehide",r),window.removeEventListener("beforeunload",r),S()}},[]),{sendPresence:u}}function Qo(s,h,z){const B=()=>{const T=Array.isArray(s.audioTracks)?s.audioTracks.length:0,N=z.getWant(),u=T>0?Math.min(Math.max(0,N),T-1):N;s.audioTrack=u,u!==N&&z.onResolve(u)},M=(T,N)=>{const u=z.getWant(),i=Array.isArray(s.audioTracks)?s.audioTracks.length:0;if(N.id!==u&&u>=0&&u<i){s.audioTrack!==u&&(s.audioTrack=u);return}z.onResolve(N.id)};return s.on(h.MANIFEST_PARSED,B),s.on(h.AUDIO_TRACK_SWITCHED,M),()=>{s.off(h.MANIFEST_PARSED,B),s.off(h.AUDIO_TRACK_SWITCHED,M)}}const Xo=/\b(SmartTV|SMART-TV|Tizen|Web0S|webOS|NetCast|HbbTV|AppleTV|CrKey|BRAVIA|AFT[A-Za-z]|Fire\s?TV|GoogleTV|Roku|VIDAA|DTV|PlayStation|Xbox|Opera TV|POV_TV)\b/i;function Zo(){try{if(Xo.test(navigator.userAgent||""))return!0;const s=navigator.deviceMemory;if(typeof s=="number"&&s>0&&s<2)return!0}catch{}return!1}const Jo="_statusMsg_zqb8u_1",ea="_error_zqb8u_7",ta="_spinner_zqb8u_11",na="_spin_zqb8u_11",ra="_sourceLoader_zqb8u_16",sa="_ringSpinner_zqb8u_22",oa="_meta_zqb8u_40",aa="_year_zqb8u_48",ia="_rating_zqb8u_53",la="_typeBadge_zqb8u_62",ca="_tv_zqb8u_70",ua="_movie_zqb8u_75",da="_controlLabel_zqb8u_80",ma="_select_zqb8u_90",ba="_playerSection_zqb8u_102",ha="_video_zqb8u_106",fa="_videoHidden_zqb8u_128",va="_delayCanvas_zqb8u_133",pa="_delayCanvasActive_zqb8u_146",ga="_subtitleOverlay_zqb8u_150",ya="_videoIframe_zqb8u_169",Sa="_retryButton_zqb8u_177",_a="_sidebarSeason_zqb8u_192",Ta="_mobileSeasonRow_zqb8u_208",Ca="_providerSelectWrap_zqb8u_222",ka="_genreRow_zqb8u_230",Ea="_genreChip_zqb8u_237",Na="_metaRow_zqb8u_247",Ia="_detailGrid_zqb8u_256",Aa="_detailItem_zqb8u_264",xa="_imdbLink_zqb8u_286",v={statusMsg:Jo,error:ea,spinner:ta,spin:na,sourceLoader:ra,ringSpinner:sa,meta:oa,year:aa,rating:ia,typeBadge:la,tv:ca,movie:ua,controlLabel:da,select:ma,playerSection:ba,video:ha,videoHidden:fa,delayCanvas:va,delayCanvasActive:pa,subtitleOverlay:ga,videoIframe:ya,retryButton:Sa,sidebarSeason:_a,mobileSeasonRow:Ta,providerSelectWrap:Ca,genreRow:ka,genreChip:Ea,metaRow:Na,detailGrid:Ia,detailItem:Aa,imdbLink:xa},wa=[],Ba=[];function fr({error:s,onRetry:h}){return t("div",{className:`${v.statusMsg} ${v.error}`,style:{flexDirection:"column",alignItems:"stretch",gap:8},children:t("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap"},children:[t("span",{style:{flex:1},children:s}),t("button",{className:v.retryButton,onClick:h,children:"Retry"})]})})}const Ya=()=>{const{id:s}=ns(),[h]=rs(),z=O(h);z.current=h;const B=ss(),M=fs(),T=h.get("type"),N=as(),u=!!N.session,i=u&&!N.session?.host,S=i&&["tv","movie"].includes(N.room?.selection.kind||"")?N.room?.selection:null,[r,L]=g(null),[he,X]=g(()=>parseInt(h.get("s")||"1",10)||1),m=S?.season??he,[ke,we]=g([]),[fe,ve]=g(()=>parseInt(h.get("e")||"1",10)||1),_=S?Number(S.episode):fe,[gt,Ze]=g(()=>{try{return D.getItem("tvProvider")||""}catch{return""}}),C=S?.provider??gt,[H,W]=g([]),[ie,yt]=g(""),[Be,Je]=g(""),{options:ee,isFallback:St,isLoading:st}=Ks(),Le=Se(()=>ee.filter(e=>(e.kind??"tv")==="tv").map(e=>({id:e.id,label:e.label,tier:e.tier==="embed"?"embed":"direct",servers:e.servers})),[ee]),G=St||Le.length===0?wa:Le,A=G.filter(e=>e.tier==="direct"),re=G.filter(e=>e.tier==="embed"),[le,Pe]=g(!1),[Me,te]=g(""),[Fe,et]=g([]),[qe,ot]=g(0),[Ee,_t]=g([]),[se,Re]=g(-1),[ze,Ue]=g(0),[tt,Tt]=g(""),[at,He]=g(""),[bn,Ct]=g(()=>{try{return D.getItem("tvServer")||""}catch{return""}}),K=S?.source??bn,it=Se(()=>G.find(e=>e.id===C),[G,C]),x=it?.tier==="embed",[oe,_e]=g([]),[pe,Z]=g(""),[Ot,lt]=g(""),[ct,kt]=g(!1),ce=Se(()=>oe.length>0?oe:it?.servers??[],[oe,it]),Et=Se(()=>pe&&!u?["Embed",...ce]:ce,[ce,pe,u]),Te=ct&&!!pe,Nt=Te?Ot||pe:"";p(()=>{if(!pe){lt("");return}let e=!1;return On(`/api/resolve?url=${encodeURIComponent(pe)}`).then(n=>{!e&&n.finalUrl&&lt(n.finalUrl)}).catch(()=>{}),()=>{e=!0}},[pe]);const It=O([]);p(()=>{It.current=H},[H]);const At=O(qe);p(()=>{At.current=qe},[qe]);const w=O(se);p(()=>{w.current=se},[se]);const c=_s({skipIntervals:Ba}),l=c.refs.videoRef,ue=O(null),de=O([]),xt=O(null),$e=O(null),{videoDelayMs:hn,videoDelayEnabled:wt,setDelayEnabled:Vt,handleVideoDelayChange:Ft,isCalibrating:fn,testClipActive:Ne,stopCalibration:vn,openAvSyncCalibrator:pr,cancelAvSyncCalibrator:gr,applyAvSyncCalibrator:yr,toggleTestClip:Sr,calibReturnRef:qt,effectiveVideoDelayMs:pn}=Ts(l),[ut,_r]=g(()=>{try{const e=Number(D.getItem("tvSubtitleDelayMs"));if(Number.isFinite(e)&&e>=-6e4&&e<=6e4)return Math.round(e)}catch{}return 0}),gn=O(ut);gn.current=ut;const Tr=E(e=>{const n=Math.max(-6e4,Math.min(6e4,Math.round(e)));if(gn.current!==n){gn.current=n,_r(n);try{D.setItem("tvSubtitleDelayMs",String(n))}catch{}}},[]);Cs({videoRef:l,canvasRef:xt,delayMs:pn,enabled:wt});const yn=wt,ge=yn||ut!==0,{settings:Sn,update:Cr}=ks(),_n=O(ge);_n.current=ge;const Tn=E(()=>{if(!_n.current)return;const e=l.current;e&&Array.from(e.textTracks).forEach(n=>{n.mode!=="hidden"&&(n.mode="hidden")})},[l]),{hasConsent:Bt,grant:kr}=is(),f=T==="movie";Go({details:r,isMovie:f,season:m,episode:_,videoRef:l,active:!x&&!le&&!Me&&H.length>0});const Ut=s?ls(T||"tv",s):"",J=Ut,De=`${J}:${m}:${_}:${C}:${K}`,Ht=Se(()=>!s||!r||x||Te||le||Be!==De||H[ze]?.type!=="hls"?null:{kind:f?"movie":"tv",...f?{}:{season:m},showId:s,episode:String(f?1:_),provider:C,source:K,mode:"sub",title:r.title},[s,r,x,Te,le,Be,De,H,ze,f,m,_,C,K]),Kn=Es(c.engine,Ht,le||!r),Yn=Ys(),Wt=js(),Kt=Gs(),{toggle:jn,bookmarkedIds:Er,pending:Nr}=Qs(),{data:Gn}=Xs(r?Ut:void 0),Lt=Gn?!!Gn.inLibrary:Ut?Er.has(Ut):!1,Ir=E(()=>{!r||!s||jn({tmdbId:Number(s),mediaType:T||"tv",title:r.title,poster:r.poster,year:r.year,adult:r.adult})},[r,s,T,jn]),{data:dt,isFetched:Qn,isFetching:Cn}=Zs(J||void 0,m,_),Yt=Se(()=>ke.map(e=>e.episode_number).sort((e,n)=>e-n),[ke]),Pt=Yt.indexOf(_),kn=Pt>0?Yt[Pt-1]:null,V=Pt>=0&&Pt<Yt.length-1?Yt[Pt+1]:null,jt=Se(()=>(r?.seasons??[]).map(e=>e.season_number).filter(e=>Number.isFinite(e)).sort((e,n)=>e-n),[r]),We=Se(()=>{if(f||V!=null)return null;const e=jt.indexOf(m);return e>=0&&e<jt.length-1?jt[e+1]:(r?.number_of_seasons??0)>m?m+1:null},[f,V,jt,m,r?.number_of_seasons]),Xn=dt?.currentTime??0,Gt=O(null),[Ke,Qt]=g(!1),[mt,Zn]=g(0),[Mt,Jn]=g(!1),[bt,ht]=g(!1),[Ar,En]=g(!1),[xr,wr]=g(""),[Xt,Br]=g(!1),[Lr,Nn]=g(!1),{isTheaterMode:Oe,toggleTheaterMode:In,handleLayoutClick:Pr}=Ns();p(()=>{const e=n=>{n.defaultPrevented||n.ctrlKey||n.metaKey||n.altKey||n.repeat||n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="t"&&In()};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[In]),Is(c,(H.length>0||at!=="")&&!Oe&&!Ke&&!bt);const Mr=no(),[ft,Rr]=g(eo),zr=E(e=>{Rr(e),to(e)},[]),Ye=O(!1),Ve=O(null),An=O(0),Q=O(null),Zt=O(""),$r=br(Xn),Rt=!u&&!Ye.current&&(Ke||bt||$r),Jt=O(Rt);Jt.current=Rt;const en=O(!1);p(()=>{en.current=Mt},[Mt]);const je=E((e,n)=>{if(!J||!n||n<30)return;const a=dn(e,n);Math.abs(e-An.current)<10&&!a||(An.current=e,Yn.mutate({mediaId:J,season:m,episode:_,currentTime:Math.floor(e),duration:Math.floor(n),completed:a,title:r?.title??null,poster:r?.poster??null,backdrop:r?.backdrop??null,year:r?.year??null,overview:r?.overview??null,tmdbId:r?.id??null,mediaType:T||"tv",adult:r?.adult?1:0}))},[J,m,_,Yn,r,T]),Ie=E((e,n)=>{vn();const a=new URLSearchParams(h);a.set("type",h.get("type")||"tv"),a.set("s",String(e)),a.set("e",String(n)),B(`${window.location.pathname}?${a.toString()}`)},[h,B,vn]),zt=E(()=>{const e=l.current;if(!e||f||V==null){En(!1);return}const n=e.duration||0,a=e.currentTime||0;En(n>0&&a/n>=.8)},[f,V,l]),tn=E((e,n)=>["tv-sources",C,f?"movie":"tv",s,e,n,K],[C,f,s,K]),nn=E(async(e,n)=>{if(!r||!s||!C)return{valid:!1,sources:[]};const a=f?"movie":"tv",d=await pt.tv.sources.query({provider:C,type:a,tmdbId:String(s),season:e,episode:n,title:r.title||"",year:r.year||"",totalSeasons:String(r.number_of_seasons||1),imdbId:r.imdb_id||"",...K?{server:K}:{}});return{valid:"valid"in d?d.valid:!1,error:"error"in d?d.error:void 0,sources:d.sources,referer:"referer"in d?d.referer:void 0,audioTracks:d.audioTracks,subtitles:"subtitles"in d?d.subtitles:void 0,servers:"servers"in d?d.servers:void 0,server:"server"in d?d.server:void 0,embedUrl:"embedUrl"in d?d.embedUrl:void 0}},[r,s,C,f,K]),er=E(()=>{if(f||!r||!s||!C||x||V==null)return;const e=tn(m,V);M.getQueryState(e)?.status!=="success"&&M.prefetchQuery({queryKey:e,queryFn:()=>nn(m,V),staleTime:300*1e3,gcTime:1800*1e3})},[f,r,s,C,x,V,m,M,tn,nn]),Dr=E(()=>{if(Ne)return;zt();const e=l.current;!e||e.paused||e.ended||(e.duration>0&&e.duration-e.currentTime<=60&&er(),!Ve.current&&(Ve.current=setTimeout(()=>{Ve.current=null,je(e.currentTime,e.duration||0)},5e3)))},[je,l,Ne,zt,er]),Or=E(()=>{const e=l.current;if(!(!e||!r)&&(Ve.current&&clearTimeout(Ve.current),Ve.current=null,je(e.currentTime,e.duration||0),!i)){if(V!=null){ft&&(ve(V),Ie(m,V));return}wr(f?r.title:`${r.title} - Season ${m}`),ht(!0),Ye.current=!0}},[f,r,m,V,ft,je,Ie,l,i]),{checkEnd:rn,logDuration:tr}=As({videoRef:l,sourceType:x?"iframe":void 0,resetKey:`${J}:${m}:${_}`,onEnd:Or}),Vr=E(()=>{c.actions.onPlay()},[c.actions]),Fr=E(()=>{c.actions.onPause();const e=l.current;e&&!e.ended&&je(e.currentTime,e.duration||0)},[c.actions,je,l]),qr=E(()=>{const e=l.current;if(e){try{const n=parseFloat(D.getItem("playerVolume")||"");isNaN(n)||(e.volume=Math.max(0,Math.min(1,n))),e.muted=D.getItem("playerMuted")==="true"}catch{}if(Q.current!=null&&Q.current>0){try{e.currentTime=Q.current}catch{}Q.current=null}zt()}},[l,zt]),xn=E(()=>{const e=l.current;if(e&&Q.current!=null&&Q.current>0){try{e.currentTime=Q.current}catch{}Q.current=null}},[l]),Ur=E(()=>{mt>0&&(Q.current=mt);const e=l.current;if(e&&mt>0){try{e.currentTime=mt,Q.current=null}catch{}e.play().catch(()=>{})}Qt(!1),Ye.current=!0},[mt,l]),nr=E(()=>{Q.current=null;const e=l.current;e&&(e.currentTime=0,e.play().catch(()=>{})),Qt(!1),Ye.current=!0},[l]),Hr=E(()=>{V!=null&&(Ye.current=!0,ve(V),Ie(m,V))},[V,m,Ie]),Wr=E(()=>{We!=null&&(ht(!1),Ye.current=!0,X(We),ve(1),Ie(We,1))},[We,Ie]),Kr=E(async()=>{if(J)try{Lt?await Wt.mutateAsync({id:J,status:"Completed"}):r&&s&&(await Kt.mutateAsync({tmdbId:Number(s),mediaType:T||"tv",title:r.title,poster:r.poster,backdrop:r.backdrop,year:r.year,overview:r.overview,adult:r.adult,status:"Completed",silent:!0}),mr.success("Moved to Completed")),ht(!1),B("/")}catch{}},[J,Lt,Wt,Kt,r,s,T,B]);p(()=>{Ye.current=!1,Gt.current=null,Qt(!1),En(!1),Zn(0),Jn(!1),en.current=!1,Q.current=null,An.current=0},[J,m,_]),p(()=>{Zt.current=De},[De]),p(()=>{Qn&&(Jn(!0),en.current=!0)},[Qn,J,m,_]),p(()=>{if(u||Cn||!dt||Ye.current)return;const e=`${J}:${m}:${_}`;if(Gt.current===e)return;Gt.current=e;const n=dt,a=n.currentTime??0;br(a)&&n.completed!==1&&!dn(a,n.duration??0)&&(Zn(a),Qt(!0))},[dt,Cn,J,m,_,u]),p(()=>{!u&&Ke&&l.current&&l.current.pause()},[Ke,l,u]),p(()=>{const e=l.current;return()=>{Ve.current&&clearTimeout(Ve.current),Ve.current=null,!e?.ended&&c.engine.getState().duration>0&&je(c.engine.getTimeline().currentTime,c.engine.getState().duration)}},[c.engine,je,l]);const wn=E(e=>{let n=null,a=!0;try{n=D.getItem("tvLastSubtitle"),a=D.getItem("tvSubtitlesEnabled")!=="false"}catch{}return Hn(e,{lastKey:n,enabled:a})},[]),Bn=E(e=>{if(!(e<0))try{D.setItem("tvSubtitlesEnabled","true"),D.setItem("tvSelectedSubtitle",String(e))}catch{}},[]),rr=E(e=>{if(e.length===0)return 0;let n=null;try{n=D.getItem("tvLastAudio")}catch{}if(n){const a=e.findIndex(q=>Vn(q)===n);if(a>=0)return a;const d=n.indexOf("|||"),b=d>=0?n.slice(0,d):n,I=d>=0?n.slice(d+3):n,F=e.findIndex(q=>q.language===b||q.label===I);if(F>=0)return F}return Hn(e,{lastKey:null,enabled:!0})},[]),{data:sr}=Js(J||void 0),or=Se(()=>(sr?.progress??[]).filter(n=>n.season===m&&(n.completed===1||dn(n.currentTime,n.duration))).map(n=>String(n.episode)),[sr,m]),ar=Se(()=>ke.map(e=>({id:String(e.episode_number),label:`Episode ${e.episode_number}`,sublabel:e.name||void 0,thumbnail:e.still_path?`https://image.tmdb.org/t/p/w185${e.still_path}`:void 0})),[ke]),ir=Se(()=>(r?.genres??[]).map(e=>e.name).slice(0,5),[r]),Ln=Se(()=>[r?.year,r?.status,r?.number_of_seasons?`${r.number_of_seasons} Season${r.number_of_seasons>1?"s":""}`:null,r?.number_of_episodes?`${r.number_of_episodes} Episodes`:null].filter(Boolean),[r]);p(()=>{if(!i&&G.length!==0&&!G.some(e=>e.id===C)){const e=G.find(n=>n.tier==="direct")?.id??G[0].id;Ze(e);try{D.setItem("tvProvider",e)}catch{}}},[G,C,i]),p(()=>{_e([]),Z(""),lt(""),kt(!1)},[C]),p(()=>{if(!i&&ce.length!==0&&!ce.includes(K)){Ct(ce[0]);try{D.setItem("tvServer",ce[0])}catch{}}},[ce,K,i]),p(()=>{if(!s){L(null),W([]),Je(""),te(""),He("");return}const e=Number(s),n=T||"tv";L(null),W([]),Je(""),te(""),He("");const a=parseInt(z.current.get("s")||"",10),d=parseInt(z.current.get("e")||"",10);X(isNaN(a)?1:a),ve(isNaN(d)?1:d),Ue(0),pt.tv.details.query({type:n,id:String(e)}).then(b=>{const I={id:b.id,title:b.title||"",overview:b.overview||"",vote_average:b.vote_average,year:b.year,poster:b.poster,backdrop:b.backdrop,imdb_id:b.imdb_id||void 0,adult:b.adult,seasons:b.seasons,number_of_seasons:b.number_of_seasons};L(I),I.seasons&&I.seasons.length>0&&isNaN(a)&&X(I.seasons[0].season_number)}).catch(()=>{})},[s,T]),p(()=>{if(!r||!s)return;if(!(r.seasons!==void 0||r.number_of_seasons!==void 0)){we([]);return}const n=parseInt(h.get("e")||"",10);pt.tv.episodes.query({id:String(s),season:String(m)}).then(a=>{const d=(a.episodes||[]).map(b=>({episode_number:b.episode_number,name:b.name||"",vote_average:b.vote_average,overview:b.overview||"",still_path:b.still_path||""}));we(d),d.length!==0&&ve(b=>!isNaN(n)&&d.some(I=>I.episode_number===n)?n:d.some(I=>I.episode_number===b)?b:d[0].episode_number)}).catch(()=>{})},[r,s,m,h]),p(()=>{if(!x||!r||!s)return;On(`/api/tv/embed/${C}/${f?"movie":"tv"}/${s}?season=${m}&episode=${_}`).then(n=>{if(n.url)return He(n.url),On(`/api/resolve?url=${encodeURIComponent(n.url)}`).then(a=>{a.finalUrl&&He(a.finalUrl)})}).catch(()=>{})},[C,r,s,m,_,f,x]);const sn=E(async()=>{if(!r||!s||!C||x||r.adult&&!Bt)return;const e=De;Pe(!0),te(""),It.current.length===0&&(W([]),Ue(0),et([]),_t([]));try{const n=await M.fetchQuery({queryKey:tn(m,_),queryFn:()=>nn(m,_),staleTime:3e5,gcTime:18e5});if(Zt.current!==e)return;if(Pe(!1),!n.valid||!n.sources?.length){te(n.error?`${n.error}`:ce.length>0?`No streams from ${K}. Try another server.`:"No streams available.");return}if(u&&K&&n.server&&n.server!==K){W([]),te("The host's selected server is unavailable. Automatic source switching is disabled in watch-along rooms.");return}!i&&!K&&n.server&&Ct(n.server);const a=u?n.sources.filter(q=>q.type==="hls"):n.sources;if(u&&a.length===0){W([]),te("The room requires a direct HLS source. No compatible stream is available here.");return}W(a),yt(n.server||K),Je(e),n.servers?.length&&_e(n.servers),n.embedUrl&&Z(n.embedUrl),Ue(0),n.referer&&Tt(n.referer);const d=n.audioTracks||[];et(d),ot(d.length>0?rr(d):0);const b=n.subtitles||[];if(_t(b),b.length>0){const q=wn(b);Re(q),Bn(q)}else Re(-1);const I=f?"movie":"tv",F=s;pt.tv.subtitles.query({type:I,tmdbId:String(F),season:String(m),episode:String(_)}).then(q=>{if(Zt.current!==e)return;const ye=Array.isArray(q.subtitles)?q.subtitles:[];ye.length!==0&&_t(y=>{const Y=[...y,...ye.filter(j=>!y.some($=>$.url===j.url))];if(y.length===0){const j=wn(Y);Re(j),Bn(j)}return Y})}).catch(()=>{}),te("")}catch(n){if(Zt.current!==e)return;Pe(!1),te(n instanceof Error?n.message:"Failed to load streams.")}},[r,s,C,m,_,f,x,Bt,ce,K,wn,Bn,rr,M,tn,nn,De,u,i]),Pn=E(()=>{const e=l.current;e&&!isNaN(e.currentTime)&&(Q.current=e.currentTime)},[l]),Yr=E(e=>{if(!(i||u&&e==="Embed")){if(e==="Embed"){kt(!0);return}Pn(),kt(!1),Ct(e);try{D.setItem("tvServer",e)}catch{}te("")}},[Pn,i,u]),jr=E(e=>{Ze(e);try{D.setItem("tvProvider",e)}catch{}},[]);p(()=>{C&&r&&!x&&sn()},[C,r,sn,x]),p(()=>{if(!l.current)return;if(ue.current=null,x||Te||u&&H[ze]?.type!=="hls"){c.engine.unload();return}if(Ne&&!u)return c.engine.loadSource({url:"/av-sync-test.mp4"},{autoPlay:!Jt.current});if(qt.current!=null&&(Q.current=qt.current,qt.current=null),Be===De&&Q.current==null&&!Jt.current)try{const y=l.current;y&&!y.ended&&y.currentTime>1&&(Q.current=y.currentTime)}catch{}const n=Q.current??0,a=!le&&Be===De?Te?"":H[ze]?.url||"":"";if(!a){try{l.current?.pause(),l.current?.removeAttribute("src"),l.current?.load()}catch{}return}const d=l.current;d.pause(),d.removeAttribute("src"),d.load(),c.actions.resetMediaState();const b=`/api/tv/stream-proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(tt)}&provider=${encodeURIComponent(C)}`,I=Zo()||document.body.classList.contains("low-end"),F=I?60:180,q=c.engine.loadSource({url:b,hls:H[ze]?.type==="hls"},{hlsConfig:{enableWorker:!0,lowLatencyMode:!1,startPosition:n>0?n:-1,maxBufferLength:F,maxMaxBufferLength:F+(I?30:60),backBufferLength:I?30:60,maxBufferSize:(I?120:360)*1e3*1e3,fragLoadPolicy:{default:{maxTimeToFirstByteMs:15e3,maxLoadTimeMs:45e3,timeoutRetry:{maxNumRetry:2,retryDelayMs:0,maxRetryDelayMs:0},errorRetry:{maxNumRetry:3,retryDelayMs:800,maxRetryDelayMs:6e3}}},manifestLoadPolicy:{default:{maxTimeToFirstByteMs:1e4,maxLoadTimeMs:25e3,timeoutRetry:{maxNumRetry:1,retryDelayMs:500,maxRetryDelayMs:2e3},errorRetry:{maxNumRetry:2,retryDelayMs:800,maxRetryDelayMs:4e3}}}},onHls:(y,Y)=>{ue.current=y;const j=()=>{let R=!1,P=0;try{R=D.getItem("tvSubtitlesEnabled")==="true";const k=parseInt(D.getItem("tvSelectedSubtitle")||"0",10);!isNaN(k)&&k>=0&&(P=k)}catch{}return{enabled:R,index:P}},$=()=>{if(typeof y.subtitleTrack!="number")return;if(de.current.length>0){y.subtitleTrack=-1;return}const R=Array.isArray(y.subtitleTracks)?y.subtitleTracks:[];if(R.length===0){y.subtitleTrack=-1;return}const P=j();if(P.enabled){const k=P.index<R.length?P.index:0;y.subtitleTrack=k,Re(k),Tn()}else y.subtitleTrack=-1};Qo(y,Y.Events,{getWant:()=>At.current,onResolve:R=>ot(R)}),y.on(Y.Events.MANIFEST_PARSED,$),y.on(Y.Events.SUBTITLE_TRACKS_UPDATED,()=>{$()}),y.on(Y.Events.SUBTITLE_TRACK_SWITCH,(R,P)=>{if(de.current.length>0){if(P.id!==-1)try{y.subtitleTrack=-1}catch{}return}const k=Array.isArray(y.subtitleTracks)?y.subtitleTracks:[];if(k.length!==0){if(P.id===-1){const Ce=j();if(Ce.enabled){const ne=Ce.index<k.length?Ce.index:0;y.subtitleTrack=ne;return}}Re(P.id),Tn()}})},onReady:()=>{(n>0||!Jt.current&&en.current)&&c.engine.play()},onError:y=>{te(y.message),Pe(!1),ue.current=null}}),ye=()=>{const j=d.error?.code===4?"Video source not supported or not found":"Failed to load video stream";te(`${j}. The source may be invalid or expired. Try switching source or reloading.`),Pe(!1)};return d.addEventListener("error",ye),()=>{q(),ue.current=null,d.removeEventListener("error",ye)}},[H,Be,le,ze,C,tt,x,Te,l,qt,Ne,J,m,_,xn,Tn,c.actions,c.engine,De,u]),p(()=>{if(i||!Mt||Ke||bt||Rt||x||Ne)return;const e=l.current;!e||!e.paused||e.ended||e.readyState<1||(xn(),c.engine.play())},[Mt,Ke,bt,Rt,x,Ne,xn,l,i,c.engine]),p(()=>{const e=ue.current;!e||typeof e.audioTrack!="number"||(e.audioTrack=qe)},[qe]),p(()=>{const e=ue.current;!e||typeof e.subtitleTrack!="number"||!Array.isArray(e.subtitleTracks)||e.subtitleTracks.length===0||de.current.length>0||(se>=0?e.subtitleTrack=se:e.subtitleTrack=-1)},[se]),p(()=>{const e=l.current;if(!(!e||x)&&(e.querySelectorAll("track").forEach(n=>n.remove()),de.current=[],Ee.length!==0&&(Ee.forEach(n=>{const a=document.createElement("track");a.kind="subtitles",a.label=n.label||n.language||"Unknown",a.srclang=n.language||n.label||"en";const d=`/api/subtitle-proxy?url=${encodeURIComponent(n.url)}&referer=${encodeURIComponent(tt)}`;a.src=d,a.addEventListener("load",()=>{const b=de.current.indexOf(a),I=a.track;if(I&&b>=0){const F=b===w.current;I.mode=F&&!_n.current?"showing":"hidden"}}),e.appendChild(a),de.current.push(a)}),Ee.length>0)))try{const n=ue.current;n&&typeof n.subtitleTrack=="number"&&n.subtitleTrack!==-1&&(n.subtitleTrack=-1)}catch{}},[Ee,tt,x,C,l]),p(()=>{const e=l.current;if(!e||x)return;const n=ue.current;de.current.length>0&&n&&typeof n.subtitleTrack=="number"&&Array.isArray(n.subtitleTracks)&&n.subtitleTracks.length>0&&(n.subtitleTrack=-1);const a=()=>{const I=Wn(c.state.subtitleFontSize,e.clientHeight||720),F=Math.max(0,Math.min(100,100-c.state.subtitlePosition)),q=()=>{const $=I*16,R=e.videoHeight||e.clientHeight||720,P=e.videoWidth||e.clientWidth||1280;return{step:$*1.3/R*100,chars:Math.max(20,Math.floor(P/($*.55)))}},ye=($,R)=>{const P=$;P.snapToLines=!1,P.line=R},y=$=>{if(!$.cues)return;Array.from($.cues).forEach(ne=>ye(ne,F));const R=Array.from($.activeCues??[]);if(R.length<=1){R.forEach(ne=>ye(ne,F));return}const{step:P,chars:k}=q();let Ce=F;for(let ne=R.length-1;ne>=0;ne--){const Ge=String(R[ne].text??"").replace(/<[^>]*>/g,"").split(`
3
3
  `).reduce((an,$t)=>an+Math.max(1,Math.ceil($t.length/k)),0);Ce=Math.max(0,Ce-Ge*P),ye(R[ne],Ce),Ce-=P*.4}},Y=de.current;if(Y.length>0){Y.forEach(($,R)=>{const P=$.track;if(!P)return;const k=R===se;P.mode=k&&!ge?"showing":"hidden",k&&!ge&&y(P)});return}const j=Array.from(e.textTracks);j.length!==0&&j.forEach(($,R)=>{const P=R===se;$.mode=P&&!ge?"showing":"hidden",P&&!ge&&y($)})};a();const d=()=>a();e.textTracks.addEventListener("addtrack",d),e.addEventListener("loadedmetadata",a,{once:!0});const b=window.setTimeout(a,600);return()=>{e.textTracks.removeEventListener("addtrack",d),e.removeEventListener("loadedmetadata",a),window.clearTimeout(b)}},[se,Ee,x,C,l,ge,c.state.subtitleFontSize,c.state.subtitlePosition]),p(()=>{if(!ge)return;const e=l.current,n=$e.current;if(!e||!n)return;const a=ut/1e3,d=pn/1e3,b=new Set;let I=[],F=-1,q=-1,ye=-1,y=-1,Y=0,j=0,$=!1;const R=()=>{const U=w.current;if(U<0)return null;const Qe=de.current;return Qe.length>0?Qe[U]?.track??null:Array.from(e.textTracks)[U]??null},P=(U,Qe)=>{const me=U.cues;if(!me||me.length===0)return Array.from(U.activeCues??[]);let nt=0,rt=me.length;for(;nt<rt;){const Ae=nt+rt>>>1;me[Ae].endTime+a<Qe?nt=Ae+1:rt=Ae}const Dt=[];for(let Ae=nt;Ae<me.length;Ae++){const ln=me[Ae];if(ln.startTime+a>Qe)break;ln.endTime+a>=Qe&&Dt.push(ln)}return Dt},k=()=>{const U=R(),Qe=e.currentTime-d,me=U?P(U,Qe):[],nt=e.clientWidth,rt=e.clientHeight,Dt=e.videoWidth,Ae=e.videoHeight;if(me.length===I.length&&me.every((zn,$n)=>zn===I[$n])&&nt===F&&rt===q&&Dt===ye&&Ae===y||(I=me,F=nt,q=rt,ye=Dt,y=Ae,n.textContent="",me.length===0))return;const ur={fontSize:Wn(c.state.subtitleFontSize,rt),position:c.state.subtitlePosition,bgOpacity:c.state.subtitleBgOpacity,bgColor:c.state.subtitleBgColor,textColor:c.state.subtitleTextColor,edge:c.state.subtitleEdge,bold:c.state.subtitleBold},Zr=xs(ur),Jr=ws(e,ur.position);me.forEach((zn,$n)=>{const dr=String(zn.text??"");if(!Bs(dr).trim())return;const Dn=document.createElement("div"),es=(me.length-1-$n)*1.7;Dn.style.cssText=`${Zr}
4
4
  bottom: calc(${Jr}px + ${es}em);`,Dn.innerHTML=Ls(dr),n.appendChild(Dn)})},Ce=()=>{Array.from(e.textTracks).forEach(U=>{b.has(U)||(b.add(U),U.addEventListener("cuechange",k))})},ne=()=>{Ce(),k()},Rn=()=>{if($||j)return;const U=()=>{j=0,!($||e.paused||e.ended)&&(k(),Rn())};j=window.requestAnimationFrame(U)},Ge=e,an=()=>{Y=0,k(),!$&&Ge.requestVideoFrameCallback&&(Y=Ge.requestVideoFrameCallback(an))},$t=()=>{k(),Ge.requestVideoFrameCallback?Y||(Y=Ge.requestVideoFrameCallback(an)):Rn()};Ce(),e.textTracks.addEventListener("addtrack",ne),e.textTracks.addEventListener("removetrack",ne),e.addEventListener("timeupdate",k),e.addEventListener("seeked",k),e.addEventListener("loadedmetadata",k),e.addEventListener("play",$t);const lr=Array.from(e.querySelectorAll("track"));lr.forEach(U=>U.addEventListener("load",k));const cr=typeof ResizeObserver>"u"?null:new ResizeObserver(()=>k());return cr?.observe(e),k(),$t(),()=>{$=!0,b.forEach(U=>U.removeEventListener("cuechange",k)),e.textTracks.removeEventListener("addtrack",ne),e.textTracks.removeEventListener("removetrack",ne),e.removeEventListener("timeupdate",k),e.removeEventListener("seeked",k),e.removeEventListener("loadedmetadata",k),e.removeEventListener("play",$t),lr.forEach(U=>U.removeEventListener("load",k)),cr?.disconnect(),j&&window.cancelAnimationFrame(j),Y&&Ge.cancelVideoFrameCallback&&Ge.cancelVideoFrameCallback(Y),n.textContent=""}},[ge,ut,se,Ee,pn,l,c.state.subtitleFontSize,c.state.subtitlePosition,c.state.subtitleBgOpacity,c.state.subtitleBgColor,c.state.subtitleTextColor,c.state.subtitleEdge,c.state.subtitleBold]);const Mn=()=>{L(null),W([]),He(""),B(-1)},Gr=E(e=>{i||(X(e),ve(1),Ie(e,1))},[Ie,i]),on=!f&&r?.seasons&&r.seasons.length>1?t("label",{className:v.sidebarSeason,children:[t("span",{children:"Season"}),t("select",{disabled:i,value:m,onChange:e=>Gr(parseInt(e.currentTarget.value,10)||1),className:v.select,children:r.seasons.map(e=>t("option",{value:e.season_number,children:["Season ",e.season_number," (",e.episode_count," ep)"]},e.season_number))})]}):null,vt=E(e=>{if(i)return;const n=parseInt(e,10);if(!isNaN(n)){try{l.current?.pause()}catch{}ve(n),Ie(m,n)}Nn(!1)},[m,Ie,l,i]);p(()=>{if(f)return;const e=n=>{n.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')||n.key.toLowerCase()==="n"&&(V!=null?vt(String(V)):mr.error("No next episode available"))};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[f,V,vt]);const Qr=e=>{ot(e);try{const a=Fe[e];a&&D.setItem("tvLastAudio",Vn(a))}catch{}const n=ue.current;n&&n.audioTrack!==void 0&&(n.audioTrack=e)},Xr=e=>{Re(e);try{if(e===-1)D.setItem("tvSubtitlesEnabled","false");else{D.setItem("tvSubtitlesEnabled","true"),D.setItem("tvSelectedSubtitle",String(e));const b=Ee[e];b&&D.setItem("tvLastSubtitle",Vn(b))}}catch{}const n=l.current,a=ue.current;if(a&&typeof a.subtitleTrack=="number"&&Array.isArray(a.subtitleTracks)&&a.subtitleTracks.length>0&&(a.subtitleTrack=de.current.length>0||e<0?-1:e),!n)return;const d=de.current;if(d.length>0){d.forEach((b,I)=>{const F=b.track;if(!F)return;const q=I===e;F.mode=q&&!ge?"showing":"hidden"});return}Array.from(n.textTracks).forEach((b,I)=>{const F=I===e;b.mode=F&&!ge?"showing":"hidden"})};return p(()=>{if(!r){document.title="TV & Movies - dango";return}document.title=f?`${r.title} - dango`:`${r.title} - Season ${m} Episode ${_} - dango`},[r,f,m,_]),p(()=>{if(!r||f)return;const e=new URLSearchParams(h),n=e.get("s"),a=e.get("e"),d=String(m),b=String(_);n===d&&a===b||(e.set("type",h.get("type")||"tv"),e.set("s",d),e.set("e",b),B(`${window.location.pathname}?${e.toString()}`,{replace:!0}))},[r,f,m,_,h,B]),t("div",{className:`${xe.playerPageLayout} ${Oe?xe.theaterMode:""} ${f?xe.noSidebar:""}`,onClick:Pr,children:[Oe&&t(Ps,{videoRef:l,active:Sn.enabled&&!x&&H.length>0&&!Me&&!(r?.adult&&!Bt),settings:Sn}),!Oe&&!f&&t("aside",{className:xe.episodeSidebar,children:r?t(Ms,{episodes:ar,currentEpisode:String(_),watchedEpisodes:or,onEpisodeClick:vt,header:on}):t(Rs,{variant:"sidebar"})}),t("div",{className:xe.playerMain,children:[r&&t("div",{className:v.playerSection,onContextMenu:e=>e.preventDefault(),style:r.adult&&!Bt?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:x&&at&&!u?t("iframe",{src:at,className:v.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!x&&Nt&&!u?t("iframe",{src:Nt,className:v.videoIframe,allow:"autoplay; fullscreen",allowFullScreen:!0}):!x&&(H.length>0||le)?t(Xe,{children:[Me&&t(fr,{error:Me,onRetry:sn}),t(Ko,{player:c,title:r.title,episodeLabel:f?void 0:`S${m} E${_}`,server:ie||it?.label||C,audioTracks:Fe,selectedAudioTrack:qe,onAudioTrackChange:Qr,subtitles:Ee,selectedSubtitle:se,onSubtitleChange:Xr,streams:H,resolutionIdx:ze,onResolutionChange:e=>{Pn(),Ue(e)},onBack:Mn,videoDelayEnabled:wt,onVideoDelayToggle:Vt,videoDelayMs:hn,onVideoDelayChange:Ft,onCalibrateAvSync:u?void 0:pr,subtitleDelayMs:ut,onSubtitleDelayChange:Tr,showNextEpisodeButton:!i&&Ar&&!Ke&&!bt,onNextEpisode:Hr,isLoading:le,isTheaterMode:Oe,onTheaterModeToggle:In,ambientSettings:Sn,onAmbientChange:Cr,children:[t(hs,{autoPlay:!u&&Mt&&!Rt,playsInline:!0,disablePictureInPicture:!0,className:`${v.video} ${yn?v.videoHidden:""}`,onTimeUpdate:()=>{Ne||(Dr(),rn())},onEnded:()=>{Ne||rn(!0)},onPlay:Vr,onPause:Fr,onSeeked:()=>{Ne||(zt(),rn())},onLoadedMetadata:()=>{qr(),tr(),rn()},onDurationChange:()=>{tr()},onContextMenu:e=>e.preventDefault(),onError:()=>{te("Video failed to load. Try another server or reload."),Pe(!1)}}),t("canvas",{ref:xt,className:`${v.delayCanvas} ${yn?v.delayCanvasActive:""}`}),ge&&t("div",{ref:$e,className:v.subtitleOverlay}),t(zs,{isOpen:fn,ms:hn,onChange:Ft,onApply:yr,onClose:gr,testClipActive:Ne,onTestClip:Sr})]})]}):Me&&!x?t(fr,{error:Me,onRetry:sn}):null}),t(so,{playback:Ht?{selection:Ht,position:l.current?.currentTime||0,playing:!1,rate:c.engine.getState().playbackRate}:null,onCreate:()=>{vn(),c.engine.pause()},needsPlayback:Kn.needsPlayback,onEnablePlayback:Kn.enablePlayback}),u&&!le&&r&&!Ht&&t("p",{role:"alert",children:"The host's direct HLS source is unavailable here. Retry or leave the room to use another source."}),!Oe&&r&&t($s,{}),!Oe&&on&&t("div",{className:v.mobileSeasonRow,children:on}),!Oe&&r&&t("div",{className:ae.streamPanel,children:[t("div",{className:v.providerSelectWrap,children:t("label",{className:v.controlLabel,children:["Provider",t("select",{value:C,onChange:e=>jr(e.currentTarget.value),className:v.select,disabled:i||G.length===0,children:st?t("option",{value:"",children:"Loading..."}):G.length===0?t("option",{value:"",children:"No providers available"}):t(Xe,{children:[A.length>0&&t("optgroup",{label:"Direct HLS",children:A.map(e=>t("option",{value:e.id,children:e.label},e.id))}),re.length>0&&t("optgroup",{label:"Embeds",children:re.map(e=>t("option",{value:e.id,children:e.label},e.id))})]})})]})}),!i&&!x&&(le?t("div",{className:v.sourceLoader,children:t("div",{className:v.ringSpinner})}):t(jo,{servers:Et,selectedServer:ct?"Embed":K,onServerSelect:Yr}))]}),!Oe&&r&&t("div",{className:xe.playerInfoContainer,children:[t("div",{className:xe.playerInfoHeader,children:[t("div",{className:xe.playerAnimeCard,children:r.poster&&t("img",{src:`https://image.tmdb.org/t/p/w342${r.poster}`,alt:r.title,loading:"lazy",decoding:"async"})}),t("div",{className:xe.videoTitleSection,children:[t("div",{className:ae.titleContainer,children:[t("h1",{children:r.title}),t("div",{className:v.meta,children:[t("span",{className:v.year,children:r.year}),r.vote_average!=null&&r.vote_average>0&&t("span",{className:v.rating,children:[t(be,{name:"star",size:12}),Number(r.vote_average).toFixed(1)]}),t("span",{className:`${v.typeBadge} ${v[f?"movie":"tv"]}`,children:f?"Movie":"TV Show"})]}),ir.length>0&&t("div",{className:v.genreRow,children:ir.map(e=>t("span",{className:v.genreChip,children:e},e))}),Ln.length>0&&t("div",{className:v.metaRow,children:Ln.map((e,n)=>t("span",{children:[e,n<Ln.length-1?" · ":""]},`${e}-${n}`))})]}),t("div",{className:ae.controls,children:[t("button",{className:`${ae.watchlistBtn} ${Lt?ae.inList:""}`,onClick:Ir,disabled:Nr,type:"button",children:[Lt?t(be,{name:"check",size:14}):t(be,{name:"plus",size:14}),Lt?"In Watchlist":"Add to Watchlist"]}),!f&&t(Xe,{children:[t("button",{className:`${ae.watchlistBtn}`,onClick:()=>kn!=null&&vt(String(kn)),disabled:i||kn==null,type:"button",children:[t(be,{name:"chevron-left",size:14}),"Prev EP"]}),t("button",{className:`${ae.watchlistBtn}`,onClick:()=>V!=null&&vt(String(V)),disabled:i||V==null,type:"button",children:["Next EP",t(be,{name:"chevron-right",size:14})]}),!f&&t("button",{className:`${ae.watchlistBtn} ${ae.modeToggleBtn} ${ft?ae.modeToggleActive:""}`,onClick:()=>zr(!ft),type:"button","aria-pressed":ft,children:ft?"AUTOPLAY: ON":"AUTOPLAY: OFF"}),Mr&&t("button",{className:`${ae.watchlistBtn}`,onClick:()=>Nn(!0),type:"button",children:[t(be,{name:"list-ul",size:14}),"Episodes"]})]})]})]})]}),t("div",{className:xe.infoColumns,children:[t("div",{className:`${ae.descriptionSection} ${ae.synopsisFlat}`,children:[t("h3",{children:"Synopsis"}),t(ro,{text:r.overview,emptyText:"No description available."}),t("button",{className:ae.detailsToggleBtn,onClick:()=>Br(!Xt),type:"button",children:[Xt?t(be,{name:"chevron-up"}):t(be,{name:"chevron-down"}),Xt?"Hide Details":"Show Details"]})]}),Xt&&t("div",{className:v.detailGrid,children:[r.first_air_date&&t("div",{className:v.detailItem,children:[t("strong",{children:f?"Release Date":"First Air Date"}),t("span",{children:r.first_air_date})]}),r.last_air_date&&t("div",{className:v.detailItem,children:[t("strong",{children:"Last Air Date"}),t("span",{children:r.last_air_date})]}),r.networks&&r.networks.length>0&&t("div",{className:v.detailItem,children:[t("strong",{children:"Networks"}),t("span",{children:r.networks.map(e=>e.name).join(", ")})]}),r.created_by&&r.created_by.length>0&&t("div",{className:v.detailItem,children:[t("strong",{children:"Created By"}),t("span",{children:r.created_by.map(e=>e.name).join(", ")})]}),r.episode_run_time&&r.episode_run_time.length>0&&t("div",{className:v.detailItem,children:[t("strong",{children:"Episode Runtime"}),t("span",{children:[r.episode_run_time[0]," min"]})]}),r.imdb_id&&t("div",{className:v.detailItem,children:[t("strong",{children:"IMDb"}),t("a",{href:`https://www.imdb.com/title/${r.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:v.imdbLink,children:"View on IMDb"})]})]})]})]}),!f&&t(Ds,{isOpen:Lr,onClose:()=>Nn(!1),episodes:ar,currentEpisode:String(_),watchedEpisodes:or,onEpisodeClick:vt,header:on}),r?.adult&&!Bt&&t(Ws,{isOpen:!0,onClose:Mn,onGrant:kr}),t(Os,{isOpen:!u&&Ke&&!Cn&&Gt.current===`${J}:${m}:${_}`&&dt?.completed!==1&&!dn(Xn,dt?.duration??0),onClose:nr,title:"Resume Watching",message:t(Xe,{children:["You were at ",t("strong",{children:Un(mt)})]}),restartLabel:"Start from Beginning",onResume:Ur,onRestart:nr}),t(Vs,{isOpen:bt,onClose:()=>ht(!1),title:f?"Movie Completed!":We!=null?"Season Complete!":"Show Completed!",heading:xr,message:f?"You finished this movie!":We!=null?`You finished Season ${m}.`:"Congratulations! You finished all available episodes.",children:[t(cn,{variant:"secondary",onClick:()=>ht(!1),children:"Close"}),We!=null?t(cn,{onClick:Wr,children:["Start Season ",We]}):t(Xe,{children:[t(cn,{onClick:()=>{ht(!1),Mn()},children:"Back to Details"}),t(cn,{onClick:Kr,disabled:Wt.isPending||Kt.isPending,children:Wt.isPending||Kt.isPending?"Saving...":"Move to Completed"})]})]}),!r&&t("div",{className:v.statusMsg,children:[t(be,{name:"spinner",className:v.spinner})," Loading..."]})]})]})};export{Ya as default};
@@ -1 +1 @@
1
- import{o as R,a as q,p as E,d as l,h as C,T,u as e,g as F}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{a8 as j,e as U,a9 as H,t as J,B as w,h as I}from"./index-BR99iwWT.js";import{c as K,d as Q}from"./useTvLibrary-DnKiDhxZ.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-BirscVrS.js";const X="_container_198yg_1",Y="_heroSection_198yg_11",Z="_bannerContainer_198yg_17",ee="_banner_198yg_17",ne="_bannerOverlay_198yg_37",te="_heroContent_198yg_49",se="_posterContainer_198yg_62",ae="_poster_198yg_62",oe="_infoGlass_198yg_86",ie="_title_198yg_100",re="_quickMeta_198yg_110",le="_metaItem_198yg_118",ce="_iconStar_198yg_126",de="_iconTv_198yg_130",me="_iconType_198yg_134",_e="_genres_198yg_139",he="_genre_198yg_139",ge="_metaRow_198yg_156",ve="_metaValue_198yg_164",pe="_metaDivider_198yg_168",ue="_synopsisSection_198yg_173",ye="_sectionTitleSmall_198yg_179",ke="_synopsis_198yg_173",be="_actions_198yg_196",Ne="_watchBtn_198yg_202",Se="_watchlistBtn_198yg_226",fe="_active_198yg_250",Ce="_seasonPickerLabel_198yg_256",Te="_seasonSelect_198yg_267",we="_detailsToggleBtn_198yg_286",Ie="_expandedContent_198yg_304",Be="_detailGrid_198yg_309",De="_detailItem_198yg_315",Me="_imdbLink_198yg_333",Le="_heroSkeleton_198yg_343",Pe="_skeletonBanner_198yg_347",$e="_skeletonContent_198yg_354",Ge="_skeletonPoster_198yg_365",xe="_skeletonInfo_198yg_373",Oe="_skeletonTitle_198yg_380",Ae="_skeletonMeta_198yg_388",Ve="_skeletonDesc_198yg_396",We="_skeletonActions_198yg_404",ze="_errorState_198yg_413",Re="_matureOverlay_198yg_434",qe="_matureContent_198yg_444",n={container:X,heroSection:Y,bannerContainer:Z,banner:ee,bannerOverlay:ne,heroContent:te,posterContainer:se,poster:ae,infoGlass:oe,title:ie,quickMeta:re,metaItem:le,iconStar:ce,iconTv:de,iconType:me,genres:_e,genre:he,metaRow:ge,metaValue:ve,metaDivider:pe,synopsisSection:ue,sectionTitleSmall:ye,synopsis:ke,actions:be,watchBtn:Ne,watchlistBtn:Se,active:fe,seasonPickerLabel:Ce,seasonSelect:Te,detailsToggleBtn:we,expandedContent:Ie,detailGrid:Be,detailItem:De,imdbLink:Me,heroSkeleton:Le,skeletonBanner:Pe,skeletonContent:$e,skeletonPoster:Ge,skeletonInfo:xe,skeletonTitle:Oe,skeletonMeta:Ae,skeletonDesc:Ve,skeletonActions:We,errorState:ze,matureOverlay:Re,matureContent:qe};function Ke(){const{id:o}=R(),c=q(),[B]=E(),i=j(B.get("type")),{hasConsent:D}=U(),[t,M]=l(null),[L,_]=l(!0),[u,y]=l(""),[d,P]=l(!1),[h,$]=l(1),G=H(i,o??""),x=Number(o),{data:O}=K(t?G:void 0),g=!!O?.inLibrary,{toggle:A}=Q();C(()=>{o&&(_(!0),y(""),J.tv.details.query({type:i,id:String(o)}).then(s=>{const m={id:s.id,title:s.title||"",overview:s.overview||"",vote_average:s.vote_average,year:s.year,poster:s.poster,backdrop:s.backdrop,imdb_id:s.imdb_id||void 0,adult:s.adult,seasons:s.seasons?.map(z=>({...z,name:""})),number_of_seasons:s.number_of_seasons};M(m),_(!1)}).catch(s=>{y(s.message),_(!1)}))},[o,i]),C(()=>{document.title=t?.title?`${t.title} - dango`:"TV & Movies - dango"},[t?.title]);const V=()=>{!o||!t||c(r?I(i,o):I(i,o,h,1))},W=()=>{t&&A({tmdbId:x,mediaType:i,title:t.title,poster:t.poster,year:t.year,adult:t.adult})},r=i==="movie",v=!r,k=t?.backdrop?`https://image.tmdb.org/t/p/w1280${t.backdrop}`:"",b=t?.poster?`https://image.tmdb.org/t/p/w500${t.poster}`:"",N=T(()=>t?.genres?t.genres.map(s=>s.name).slice(0,5):[],[t?.genres]),S=T(()=>t?.seasons?t.seasons.filter(s=>s.season_number>0):[],[t?.seasons]),p=[t?.year,t?.status,v&&t?.number_of_seasons?`${t.number_of_seasons} Season${t.number_of_seasons>1?"s":""}`:null,v&&t?.number_of_episodes?`${t.number_of_episodes} Episodes`:null].filter(Boolean);if(L)return e("div",{className:n.container,children:e("div",{className:n.heroSkeleton,children:[e("div",{className:n.skeletonBanner}),e("div",{className:n.skeletonContent,children:[e("div",{className:n.skeletonPoster}),e("div",{className:n.skeletonInfo,children:[e("div",{className:n.skeletonTitle}),e("div",{className:n.skeletonMeta}),e("div",{className:n.skeletonDesc}),e("div",{className:n.skeletonActions})]})]})]})});if(u||!t)return e("div",{className:n.container,children:e("div",{className:n.errorState,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Failed to load details"}),e("p",{children:u||"Something went wrong"}),e(w,{onClick:()=>c(-1),children:"Go Back"})]})});const f=t.adult&&!D;return e("div",{className:n.container,style:f?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:[e("div",{className:n.heroSection,children:[e("div",{className:n.bannerContainer,children:[k&&e("div",{className:n.banner,style:{backgroundImage:`url(${k})`}}),e("div",{className:n.bannerOverlay})]}),e("div",{className:n.heroContent,children:[e("div",{className:n.posterContainer,children:b&&e("img",{src:b,alt:t.title,className:n.poster,decoding:"async"})}),e("div",{className:n.infoGlass,children:[e("div",{children:[e("h1",{className:n.title,children:t.title}),e("div",{className:n.quickMeta,children:[t.vote_average!=null&&t.vote_average>0&&e("div",{className:n.metaItem,children:[e(a,{name:"star",className:n.iconStar}),e("span",{children:Number(t.vote_average).toFixed(1)})]}),e("div",{className:n.metaItem,children:[e(a,{name:"tv",className:n.iconTv}),e("span",{children:r?"Movie":"TV Show"})]}),t.vote_count!=null&&e("div",{className:n.metaItem,children:[e(a,{name:"users",className:n.iconType}),e("span",{children:[t.vote_count.toLocaleString()," votes"]})]})]}),N.length>0&&e("div",{className:n.genres,children:N.map(s=>e("span",{className:n.genre,children:s},s))})]}),p.length>0&&e("div",{className:n.metaRow,children:p.map((s,m)=>e(F.Fragment,{children:[e("span",{className:n.metaValue,children:s}),m<p.length-1&&e("span",{className:n.metaDivider,children:"·"})]},m))}),t.overview&&e("div",{className:n.synopsisSection,children:[e("h2",{className:n.sectionTitleSmall,children:"Synopsis"}),e("p",{className:n.synopsis,children:t.overview})]}),e("div",{className:n.actions,children:[e("button",{className:n.watchBtn,onClick:V,children:[e(a,{name:"play",size:14}),r?"Watch Now":`Start S${h}`]}),e("button",{className:`${n.watchlistBtn} ${g?n.active:""}`,onClick:W,children:[g?e(a,{name:"check",size:14}):e(a,{name:"plus",size:14}),g?"In Watchlist":"Add to Watchlist"]})]}),v&&S.length>1&&e("label",{className:n.seasonPickerLabel,children:[e("span",{children:"Season"}),e("select",{value:h,onChange:s=>$(parseInt(s.currentTarget.value,10)||1),className:n.seasonSelect,children:S.map(s=>e("option",{value:s.season_number,children:["Season ",s.season_number," (",s.episode_count," Episodes)"]},s.season_number))})]}),e("button",{className:n.detailsToggleBtn,onClick:()=>P(!d),children:[d?e(a,{name:"chevron-up"}):e(a,{name:"chevron-down"}),d?"Hide Details":"Show Details"]}),d&&e("div",{className:n.expandedContent,children:e("div",{className:n.detailGrid,children:[t.first_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:r?"Release Date":"First Air Date"}),e("span",{children:t.first_air_date})]}),t.last_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:"Last Air Date"}),e("span",{children:t.last_air_date})]}),t.networks&&t.networks.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Networks"}),e("span",{children:t.networks.map(s=>s.name).join(", ")})]}),t.created_by&&t.created_by.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Created By"}),e("span",{children:t.created_by.map(s=>s.name).join(", ")})]}),t.episode_run_time&&t.episode_run_time.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Episode Runtime"}),e("span",{children:[t.episode_run_time[0]," min"]})]}),t.imdb_id&&e("div",{className:n.detailItem,children:[e("strong",{children:"IMDb"}),e("a",{href:`https://www.imdb.com/title/${t.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:n.imdbLink,children:"View on IMDb"})]})]})})]})]})]}),f&&e("div",{className:n.matureOverlay,children:e("div",{className:n.matureContent,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Content Warning"}),e("p",{children:"This content may contain mature themes."}),e(w,{onClick:()=>c("/"),children:"Go Back"})]})})]})}export{Ke as default};
1
+ import{o as R,a as q,p as E,d as l,h as C,T,u as e,g as F}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{a8 as j,e as U,a9 as H,t as J,B as w,h as I}from"./index-fS4AGBy2.js";import{c as K,d as Q}from"./useTvLibrary-D6KqZu5s.js";import"./vendor-query-BBT5_sHx.js";import"./libraryInvalidation-C4kz8swK.js";const X="_container_198yg_1",Y="_heroSection_198yg_11",Z="_bannerContainer_198yg_17",ee="_banner_198yg_17",ne="_bannerOverlay_198yg_37",te="_heroContent_198yg_49",se="_posterContainer_198yg_62",ae="_poster_198yg_62",oe="_infoGlass_198yg_86",ie="_title_198yg_100",re="_quickMeta_198yg_110",le="_metaItem_198yg_118",ce="_iconStar_198yg_126",de="_iconTv_198yg_130",me="_iconType_198yg_134",_e="_genres_198yg_139",he="_genre_198yg_139",ge="_metaRow_198yg_156",ve="_metaValue_198yg_164",pe="_metaDivider_198yg_168",ue="_synopsisSection_198yg_173",ye="_sectionTitleSmall_198yg_179",ke="_synopsis_198yg_173",be="_actions_198yg_196",Ne="_watchBtn_198yg_202",Se="_watchlistBtn_198yg_226",fe="_active_198yg_250",Ce="_seasonPickerLabel_198yg_256",Te="_seasonSelect_198yg_267",we="_detailsToggleBtn_198yg_286",Ie="_expandedContent_198yg_304",Be="_detailGrid_198yg_309",De="_detailItem_198yg_315",Me="_imdbLink_198yg_333",Le="_heroSkeleton_198yg_343",Pe="_skeletonBanner_198yg_347",$e="_skeletonContent_198yg_354",Ge="_skeletonPoster_198yg_365",xe="_skeletonInfo_198yg_373",Oe="_skeletonTitle_198yg_380",Ae="_skeletonMeta_198yg_388",Ve="_skeletonDesc_198yg_396",We="_skeletonActions_198yg_404",ze="_errorState_198yg_413",Re="_matureOverlay_198yg_434",qe="_matureContent_198yg_444",n={container:X,heroSection:Y,bannerContainer:Z,banner:ee,bannerOverlay:ne,heroContent:te,posterContainer:se,poster:ae,infoGlass:oe,title:ie,quickMeta:re,metaItem:le,iconStar:ce,iconTv:de,iconType:me,genres:_e,genre:he,metaRow:ge,metaValue:ve,metaDivider:pe,synopsisSection:ue,sectionTitleSmall:ye,synopsis:ke,actions:be,watchBtn:Ne,watchlistBtn:Se,active:fe,seasonPickerLabel:Ce,seasonSelect:Te,detailsToggleBtn:we,expandedContent:Ie,detailGrid:Be,detailItem:De,imdbLink:Me,heroSkeleton:Le,skeletonBanner:Pe,skeletonContent:$e,skeletonPoster:Ge,skeletonInfo:xe,skeletonTitle:Oe,skeletonMeta:Ae,skeletonDesc:Ve,skeletonActions:We,errorState:ze,matureOverlay:Re,matureContent:qe};function Ke(){const{id:o}=R(),c=q(),[B]=E(),i=j(B.get("type")),{hasConsent:D}=U(),[t,M]=l(null),[L,_]=l(!0),[u,y]=l(""),[d,P]=l(!1),[h,$]=l(1),G=H(i,o??""),x=Number(o),{data:O}=K(t?G:void 0),g=!!O?.inLibrary,{toggle:A}=Q();C(()=>{o&&(_(!0),y(""),J.tv.details.query({type:i,id:String(o)}).then(s=>{const m={id:s.id,title:s.title||"",overview:s.overview||"",vote_average:s.vote_average,year:s.year,poster:s.poster,backdrop:s.backdrop,imdb_id:s.imdb_id||void 0,adult:s.adult,seasons:s.seasons?.map(z=>({...z,name:""})),number_of_seasons:s.number_of_seasons};M(m),_(!1)}).catch(s=>{y(s.message),_(!1)}))},[o,i]),C(()=>{document.title=t?.title?`${t.title} - dango`:"TV & Movies - dango"},[t?.title]);const V=()=>{!o||!t||c(r?I(i,o):I(i,o,h,1))},W=()=>{t&&A({tmdbId:x,mediaType:i,title:t.title,poster:t.poster,year:t.year,adult:t.adult})},r=i==="movie",v=!r,k=t?.backdrop?`https://image.tmdb.org/t/p/w1280${t.backdrop}`:"",b=t?.poster?`https://image.tmdb.org/t/p/w500${t.poster}`:"",N=T(()=>t?.genres?t.genres.map(s=>s.name).slice(0,5):[],[t?.genres]),S=T(()=>t?.seasons?t.seasons.filter(s=>s.season_number>0):[],[t?.seasons]),p=[t?.year,t?.status,v&&t?.number_of_seasons?`${t.number_of_seasons} Season${t.number_of_seasons>1?"s":""}`:null,v&&t?.number_of_episodes?`${t.number_of_episodes} Episodes`:null].filter(Boolean);if(L)return e("div",{className:n.container,children:e("div",{className:n.heroSkeleton,children:[e("div",{className:n.skeletonBanner}),e("div",{className:n.skeletonContent,children:[e("div",{className:n.skeletonPoster}),e("div",{className:n.skeletonInfo,children:[e("div",{className:n.skeletonTitle}),e("div",{className:n.skeletonMeta}),e("div",{className:n.skeletonDesc}),e("div",{className:n.skeletonActions})]})]})]})});if(u||!t)return e("div",{className:n.container,children:e("div",{className:n.errorState,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Failed to load details"}),e("p",{children:u||"Something went wrong"}),e(w,{onClick:()=>c(-1),children:"Go Back"})]})});const f=t.adult&&!D;return e("div",{className:n.container,style:f?{filter:"blur(14px)",pointerEvents:"none",userSelect:"none"}:void 0,children:[e("div",{className:n.heroSection,children:[e("div",{className:n.bannerContainer,children:[k&&e("div",{className:n.banner,style:{backgroundImage:`url(${k})`}}),e("div",{className:n.bannerOverlay})]}),e("div",{className:n.heroContent,children:[e("div",{className:n.posterContainer,children:b&&e("img",{src:b,alt:t.title,className:n.poster,decoding:"async"})}),e("div",{className:n.infoGlass,children:[e("div",{children:[e("h1",{className:n.title,children:t.title}),e("div",{className:n.quickMeta,children:[t.vote_average!=null&&t.vote_average>0&&e("div",{className:n.metaItem,children:[e(a,{name:"star",className:n.iconStar}),e("span",{children:Number(t.vote_average).toFixed(1)})]}),e("div",{className:n.metaItem,children:[e(a,{name:"tv",className:n.iconTv}),e("span",{children:r?"Movie":"TV Show"})]}),t.vote_count!=null&&e("div",{className:n.metaItem,children:[e(a,{name:"users",className:n.iconType}),e("span",{children:[t.vote_count.toLocaleString()," votes"]})]})]}),N.length>0&&e("div",{className:n.genres,children:N.map(s=>e("span",{className:n.genre,children:s},s))})]}),p.length>0&&e("div",{className:n.metaRow,children:p.map((s,m)=>e(F.Fragment,{children:[e("span",{className:n.metaValue,children:s}),m<p.length-1&&e("span",{className:n.metaDivider,children:"·"})]},m))}),t.overview&&e("div",{className:n.synopsisSection,children:[e("h2",{className:n.sectionTitleSmall,children:"Synopsis"}),e("p",{className:n.synopsis,children:t.overview})]}),e("div",{className:n.actions,children:[e("button",{className:n.watchBtn,onClick:V,children:[e(a,{name:"play",size:14}),r?"Watch Now":`Start S${h}`]}),e("button",{className:`${n.watchlistBtn} ${g?n.active:""}`,onClick:W,children:[g?e(a,{name:"check",size:14}):e(a,{name:"plus",size:14}),g?"In Watchlist":"Add to Watchlist"]})]}),v&&S.length>1&&e("label",{className:n.seasonPickerLabel,children:[e("span",{children:"Season"}),e("select",{value:h,onChange:s=>$(parseInt(s.currentTarget.value,10)||1),className:n.seasonSelect,children:S.map(s=>e("option",{value:s.season_number,children:["Season ",s.season_number," (",s.episode_count," Episodes)"]},s.season_number))})]}),e("button",{className:n.detailsToggleBtn,onClick:()=>P(!d),children:[d?e(a,{name:"chevron-up"}):e(a,{name:"chevron-down"}),d?"Hide Details":"Show Details"]}),d&&e("div",{className:n.expandedContent,children:e("div",{className:n.detailGrid,children:[t.first_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:r?"Release Date":"First Air Date"}),e("span",{children:t.first_air_date})]}),t.last_air_date&&e("div",{className:n.detailItem,children:[e("strong",{children:"Last Air Date"}),e("span",{children:t.last_air_date})]}),t.networks&&t.networks.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Networks"}),e("span",{children:t.networks.map(s=>s.name).join(", ")})]}),t.created_by&&t.created_by.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Created By"}),e("span",{children:t.created_by.map(s=>s.name).join(", ")})]}),t.episode_run_time&&t.episode_run_time.length>0&&e("div",{className:n.detailItem,children:[e("strong",{children:"Episode Runtime"}),e("span",{children:[t.episode_run_time[0]," min"]})]}),t.imdb_id&&e("div",{className:n.detailItem,children:[e("strong",{children:"IMDb"}),e("a",{href:`https://www.imdb.com/title/${t.imdb_id}`,target:"_blank",rel:"noopener noreferrer",className:n.imdbLink,children:"View on IMDb"})]})]})})]})]})]}),f&&e("div",{className:n.matureOverlay,children:e("div",{className:n.matureContent,children:[e(a,{name:"exclamation-triangle",size:48}),e("h2",{children:"Content Warning"}),e("p",{children:"This content may contain mature themes."}),e(w,{onClick:()=>c("/"),children:"Go Back"})]})})]})}export{Ke as default};