kv-netflix/backend/static/assets/watch-Baf19X1S.js

104 lines
24 KiB
JavaScript

import{a as h,s as v,i as I,d as C}from"./Toast-BwR22KmJ.js";const s={video:null,currentEpisode:1,currentServer:0,recommendations:[],isLoading:!0};window.state=s;let t={};function k(){var e,i;t={videoPlayer:document.getElementById("videoPlayer"),videoPlayerContainer:document.getElementById("videoPlayerContainer"),playerLoading:document.getElementById("playerLoading"),closePlayer:document.getElementById("closePlayer"),heroBg:document.getElementById("heroBg"),movieTitle:document.getElementById("movieTitleDesktop"),movieMatch:document.getElementById("movieMatchDesktop"),movieYear:document.getElementById("movieYearDesktop"),movieRating:document.getElementById("movieRatingDesktop"),movieQuality:document.getElementById("movieQualityDesktop"),movieDescription:document.getElementById("movieDescriptionDesktop"),movieTags:document.getElementById("movieTags"),movieTitleMobile:document.getElementById("movieTitleMobile"),movieMatchMobile:document.getElementById("movieMatchMobile"),movieYearMobile:document.getElementById("movieYearMobile"),movieRatingMobile:document.getElementById("movieRatingMobile"),movieDuration:document.getElementById("movieDurationDesktop"),movieDurationMobile:document.getElementById("movieDurationMobile"),movieQualityMobile:document.getElementById("movieQualityMobile"),movieDescriptionMobile:document.getElementById("movieDescriptionMobile"),playBtn:document.getElementById("playBtnDesktop"),addListBtn:document.getElementById("addListBtnDesktop"),addListIcon:(e=document.getElementById("addListBtnDesktop"))==null?void 0:e.querySelector(".material-symbols-outlined"),addListText:(i=document.getElementById("addListBtnDesktop"))==null?void 0:i.querySelector("span:last-child"),playBtnMobile:document.getElementById("playBtnMobile"),addListBtnMobile:document.getElementById("addListBtnMobile"),shareBtnMobile:document.getElementById("shareBtnMobile"),mobilePlayBtn:document.getElementById("mobilePlayBtn"),watchHeader:document.getElementById("watchHeader"),tabNav:document.getElementById("tabNav"),watchBackBtn:document.getElementById("watchBackBtn"),episodesPanel:document.getElementById("episodesPanel"),trailersPanel:document.getElementById("trailersPanel"),detailsPanel:document.getElementById("detailsPanel"),seasonSelect:document.getElementById("seasonSelect"),seasonSelectContainer:document.getElementById("seasonSelectContainer"),episodeCount:document.getElementById("episodeCount"),episodesGrid:document.getElementById("episodesGrid"),episodesLoading:document.getElementById("episodesLoading"),castCarousel:document.getElementById("castCarousel"),recommendationsContainer:document.getElementById("recommendationsContainer"),detailsList:document.getElementById("detailsList"),searchModal:document.getElementById("searchModal"),searchBtn:document.getElementById("searchBtn"),searchInput:document.getElementById("searchInput"),closeSearch:document.getElementById("closeSearch")}}async function w(){const e=new URLSearchParams(window.location.search),i=e.get("id"),r=e.get("slug"),o=parseInt(e.get("ep"))||1;if(s.currentEpisode=o,!i&&!r){B("No video specified");return}k(),$(),await T(i,r),await j()}function $(){if(window.addEventListener("scroll",()=>{t.watchHeader&&(window.scrollY>50?t.watchHeader.style.backgroundColor="rgba(20,20,20,0.95)":t.watchHeader.style.backgroundColor="transparent")}),t.watchBackBtn&&t.watchBackBtn.addEventListener("click",i=>{i.preventDefault(),t.videoPlayerContainer&&(t.videoPlayerContainer.style.display!=="none"||!t.videoPlayerContainer.classList.contains("hidden"))?b():document.referrer&&document.referrer.includes(window.location.host)?window.history.back():window.location.href="/index.html"}),document.addEventListener("keydown",i=>{i.key==="Escape"&&(t.videoPlayerContainer&&!t.videoPlayerContainer.classList.contains("hidden")&&b(),t.searchModal&&!t.searchModal.classList.contains("hidden")&&t.searchModal.classList.add("hidden"))}),[t.playBtn,t.playBtnMobile,t.mobilePlayBtn].forEach(i=>{i&&i.addEventListener("click",()=>{t.videoPlayerContainer&&(t.videoPlayerContainer.classList.remove("hidden"),t.videoPlayerContainer.style.display="block"),t.videoPlayer&&(t.videoPlayer.style.display="block"),M()})}),t.closePlayer&&t.closePlayer.addEventListener("click",()=>{b()}),t.searchBtn&&t.searchBtn.addEventListener("click",()=>{t.searchModal&&(t.searchModal.classList.remove("hidden"),setTimeout(()=>{var i;return(i=t.searchInput)==null?void 0:i.focus()},100))}),t.closeSearch&&t.closeSearch.addEventListener("click",()=>{t.searchModal&&t.searchModal.classList.add("hidden")}),[t.addListBtn,t.addListBtnMobile].forEach(i=>{i&&i.addEventListener("click",()=>{var o;if(!s.video)return;const r=(o=window.historyService)==null?void 0:o.toggleFavorite(s.video);x(r),r?v("Added to My List","success"):v("Removed from My List","info")})}),t.shareBtnMobile&&t.shareBtnMobile.addEventListener("click",()=>{var i;navigator.share?navigator.share({title:((i=s.video)==null?void 0:i.title)||"StreamFlix",url:window.location.href}):(navigator.clipboard.writeText(window.location.href),v("Link copied to clipboard","success"))}),t.tabNav){const i=t.tabNav.querySelectorAll(".tab-btn"),r={episodes:t.episodesPanel,details:t.detailsPanel};i.forEach(o=>{o.addEventListener("click",()=>{const n=o.dataset.tab;i.forEach(l=>{l.classList.remove("text-white","font-bold","border-b-4","border-primary"),l.classList.add("text-gray-400","font-medium")}),o.classList.remove("text-gray-400","font-medium"),o.classList.add("text-white","font-bold","border-b-4","border-primary"),Object.entries(r).forEach(([l,d])=>{d&&(l===n?d.classList.remove("hidden"):d.classList.add("hidden"))})})})}document.querySelectorAll("#mobileBottomNav .nav-item").forEach(i=>{i.addEventListener("click",r=>{r.preventDefault();const o=i.dataset.view;o&&(window.location.href=`/index.html?view=${o}`)})})}function b(){const e=t.videoPlayerContainer||document.getElementById("videoPlayerContainer"),i=t.videoPlayer||document.getElementById("videoPlayer"),r=t.playerLoading||document.getElementById("playerLoading");e&&(e.classList.add("hidden"),e.style.display="none"),C(),i&&(i.innerHTML="",i.style.display="none"),r&&(r.style.display="none")}function x(e){const i=e?"check":"add",r=e?"In List":"My List";if(t.addListBtn){const o=t.addListBtn.querySelector(".material-symbols-outlined"),n=t.addListBtn.querySelector("span:last-child");o&&(o.textContent=i),n&&(n.textContent=r),e?t.addListBtn.classList.add("bg-white/20"):t.addListBtn.classList.remove("bg-white/20")}if(t.addListBtnMobile){const o=t.addListBtnMobile.querySelector(".material-symbols-outlined"),n=t.addListBtnMobile.querySelector("span:last-child");o&&(o.textContent=i),n&&(n.textContent=r),e?(t.addListBtnMobile.classList.add("bg-white/10"),t.addListBtnMobile.classList.remove("bg-[#2b2b2b]")):(t.addListBtnMobile.classList.remove("bg-white/10"),t.addListBtnMobile.classList.add("bg-[#2b2b2b]"))}}async function T(e,i){var r,o,n,l,d,c;try{s.isLoading=!0;let m=null;const u=i||e;if(u)try{const p=await h.getRophimMovie(u);if(p){const a=p.movie||p,y=p.episodes||[];m={id:a.slug||u,slug:a.slug||u,title:a.name||a.title||u,original_title:a.origin_name||a.original_title||"",description:a.content||a.description||"",thumbnail:a.poster_url||a.thumb_url||a.thumbnail||"",year:a.year,rating:((r=a.tmdb)==null?void 0:r.vote_average)||a.rating||"N/A",quality:a.quality||"HD",duration:a.time||a.duration||"",genres:Array.isArray(a.category)?a.category.map(g=>g.name||g):Array.isArray(a.genres)?a.genres:typeof a.genre=="string"?a.genre.split(",").map(g=>g.trim()):[],country:((n=(o=a.country)==null?void 0:o[0])==null?void 0:n.name)||a.country||"",country:((d=(l=a.country)==null?void 0:l[0])==null?void 0:d.name)||a.country||"",cast:a.actor||a.cast||[],director:((c=a.director)==null?void 0:c[0])||a.director||"",source_url:`https://phimmoichill.network/phim/${u}`,episodes:P(y)}}}catch(p){console.warn("API fetch failed:",p)}if(!m)throw new Error("Video data not found");s.video=m,window.historyService&&window.historyService.addToHistory(m,{episode:s.currentEpisode}),_(m),window.historyService&&x(window.historyService.isFavorite(m.slug))}catch(m){console.error("Failed to load video:",m),B("Failed to load video data")}finally{s.isLoading=!1}}function P(e){if(!e||!Array.isArray(e)||e.length===0)return[];const i=e[0];return((i==null?void 0:i.server_data)||[]).map((o,n)=>({number:n+1,name:o.name||`Episode ${n+1}`,title:o.filename||`Episode ${n+1}`,slug:o.slug||"",link_embed:o.link_embed||"",link_m3u8:o.link_m3u8||""}))}function _(e){if(t.heroBg){const i=e.backdrop||e.poster_url||e.thumb_url||e.thumbnail||"";i&&(t.heroBg.style.backgroundImage=`url('${i}')`)}if(t.movieTitle&&(t.movieTitle.textContent=e.title),t.movieYear&&(t.movieYear.textContent=e.year||""),t.movieDuration)if(e.runtime_minutes){const i=Math.floor(e.runtime_minutes/60),r=e.runtime_minutes%60;t.movieDuration.textContent=i>0?`${i}h ${r}m`:`${r}m`}else e.duration&&(t.movieDuration.textContent=e.duration);if(t.movieQuality&&(t.movieQuality.textContent=e.quality||"HD"),t.movieRating){const i=e.rating||e.tmdb_rating;i&&i!=="N/A"?t.movieRating.textContent=typeof i=="number"?`${i.toFixed(1)}`:i:t.movieRating.textContent="TV-MA"}if(t.movieMatch){const i=Math.floor(85+Math.random()*14);t.movieMatch.textContent=`${i}% Match`}if(t.movieDescription){const i=e.tmdb_description||e.description||"No description available.";t.movieDescription.innerHTML=i,t.movieDescriptionMobile&&(t.movieDescriptionMobile.innerHTML=i)}if(t.movieTitleMobile&&(t.movieTitleMobile.textContent=e.title),t.movieYearMobile&&(t.movieYearMobile.textContent=e.year||""),t.movieRatingMobile){const i=e.rating||e.tmdb_rating;t.movieRatingMobile.textContent=i&&i!=="N/A"?typeof i=="number"?i.toFixed(1):i:"TV-MA"}if(t.movieDurationMobile&&(t.movieDurationMobile.textContent=t.movieDuration?t.movieDuration.textContent:e.duration||""),t.movieQualityMobile&&(t.movieQualityMobile.textContent=e.quality||"HD"),t.movieMatchMobile&&t.movieMatch&&(t.movieMatchMobile.textContent=t.movieMatch.textContent),t.movieTags){const i=e.genres||[],r=e.director,o=e.country;let n="";i.length>0&&(n+=`<div><span class="text-white/50">Genres:</span> <span class="text-white">${i.join(", ")}</span></div>`),r&&r!=="Unknown"&&(n+=`<div><span class="text-white/50">Director:</span> <span class="text-white">${r}</span></div>`),o&&o!=="Unknown"&&(n+=`<div><span class="text-white/50">Country:</span> <span class="text-white">${o}</span></div>`),t.movieTags.innerHTML=n}document.title=`${e.title} - StreamFlix`,window.historyService&&e.slug&&x(window.historyService.isFavorite(e.slug)),L(e),e.tmdb_cast&&e.tmdb_cast.length>0?E(e.tmdb_cast,!0):e.cast&&e.cast.length>0&&E(e.cast,!1),S(e)}function L(e){if(!t.episodesPanel)return;let i=[];if(Array.isArray(e.episodes)&&e.episodes.length>0&&(e.episodes[0].server_data?i=e.episodes[0].server_data:i=e.episodes),i.length<=1){t.seasonSelectContainer&&(t.seasonSelectContainer.style.display="none"),t.episodesLoading&&(t.episodesLoading.style.display="none"),t.episodesGrid&&(t.episodesGrid.innerHTML=`
<div class="flex items-center gap-4 p-4 bg-surface-dark rounded-lg border border-white/5">
<span class="material-symbols-outlined text-3xl text-primary">play_circle</span>
<div>
<p class="text-white font-medium">Full Movie</p>
<p class="text-gray-400 text-sm">Click Play to watch</p>
</div>
</div>
`);return}if(t.episodeCount&&(t.episodeCount.textContent=`${i.length} Episodes`),t.episodesLoading&&(t.episodesLoading.style.display="none"),t.episodesGrid){const o=i.length,n=o<=15,l=d=>{if(t.episodesGrid.innerHTML=i.slice(0,d).map((c,m)=>{const u=m+1,p=u===s.currentEpisode,a=c.name||`Episode ${u}`,y=c.title||c.filename||"";return`
<div class="flex items-start gap-4 p-4 rounded-lg cursor-pointer transition-colors hover:bg-surface-dark border border-transparent hover:border-white/10 ${p?"bg-surface-dark border-primary/40":""}" onclick="window.selectEpisode(${u})">
<div class="flex-none text-2xl font-bold text-gray-500 w-8 text-center">${u}</div>
<div class="flex-1">
<h4 class="text-white font-medium ${p?"text-primary":""}">${a}</h4>
${y?`<p class="text-gray-400 text-sm mt-1 line-clamp-2">${y}</p>`:""}
</div>
${p?'<span class="material-symbols-outlined text-primary">play_circle</span>':""}
</div>
`}).join(""),d<o){const c=document.createElement("button");c.className="w-full py-4 text-gray-400 hover:text-white font-medium flex items-center justify-center gap-2 border-t border-white/5 mt-2 transition-colors",c.innerHTML=`
<span>See more episodes (${o-d} remaining)</span>
<span class="material-symbols-outlined">expand_more</span>
`,c.onclick=()=>l(o),t.episodesGrid.appendChild(c)}};l(n?o:10)}}function S(e){if(!t.detailsList)return;const i=[];e.original_title&&i.push({label:"Original Title",value:e.original_title}),e.director&&e.director!=="Unknown"&&i.push({label:"Director",value:e.director}),e.country&&e.country!=="Unknown"&&i.push({label:"Country",value:e.country}),e.year&&i.push({label:"Release Year",value:e.year}),e.quality&&i.push({label:"Quality",value:e.quality}),e.duration&&i.push({label:"Duration",value:e.duration}),e.genres&&e.genres.length>0&&i.push({label:"Genres",value:e.genres.join(", ")}),t.detailsList.innerHTML="",i.forEach(r=>{const o=document.createElement("div");o.className="flex gap-4";const n=document.createElement("span");n.className="text-white/50 min-w-[100px] font-medium",n.textContent=`${r.label}:`;const l=document.createElement("span");l.className="text-white font-medium",l.textContent=r.value,o.appendChild(n),o.appendChild(l),t.detailsList.appendChild(o)})}window.selectEpisode=e=>{s.currentEpisode=e;const i=new URL(window.location);i.searchParams.set("ep",e),window.history.replaceState({},"",i),L(s.video),M(),window.scrollTo({top:0,behavior:"smooth"})};async function M(){if(s.video){t.playerLoading&&(t.playerLoading.style.display="flex");try{let e=null,i=s.video.thumbnail,r=[];Array.isArray(s.video.episodes)&&s.video.episodes.length>0&&(s.video.episodes[0].server_data?r=s.video.episodes[0].server_data:r=s.video.episodes);const o=r[s.currentEpisode-1];if(window.historyService&&window.historyService.addToHistory(s.video,{episode:s.currentEpisode,timestamp:Date.now()}),o&&(o.link_m3u8?e=o.link_m3u8:o.link_embed&&(e=o.link_embed)),!e&&s.video.slug)try{const n=await h.getRophimStream(s.video.slug,s.currentEpisode);n!=null&&n.stream_url&&(e=n.stream_url)}catch(n){console.warn("Stream API fallback also failed",n)}if(t.playerLoading&&(t.playerLoading.style.display="none"),e){H(e,i,s.video.title);const n=r.length>1?`Episode ${s.currentEpisode} `:"Movie";v(`Playing ${n} `,"success")}else{const n=s.currentEpisode===1?"full":s.currentEpisode,l=`https://phimmoichill.network/xem-phim/${s.video.slug}/tap-${n}-sv-0`;D(l)}}catch(e){console.error(e),A(e.message)}}}function D(e){t.videoPlayer.innerHTML=`
<div style="display:flex;height:100%;align-items:center;justify-content:center;flex-direction:column;gap:20px;padding:40px;text-align:center;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="64" height="64" style="color:#ff4d4d; opacity: 0.8;">
<circle cx="12" cy="12" r="10"/>
<line x1="15" y1="9" x2="9" y2="15"/>
<line x1="9" y1="9" x2="15" y2="15"/>
</svg>
<h3 style="color:#fff;margin:0;font-size:1.5rem;">It cannot load</h3>
<p style="color:#aaa;margin:0;max-width:400px;opacity:0.7;">This stream is currently unavailable. Please try again later or choose another source.</p>
</div>
`}function H(e,i,r){if(e.includes("embed")||!e.match(/\.(mp4|m3u8)$/i))t.videoPlayer.innerHTML=`
<iframe src="${e}" allowfullscreen allow="autoplay; encrypted-media"></iframe>
`;else{const n=I(t.videoPlayer,{url:e,poster:i,title:r+` - Ep ${s.currentEpisode}`,autoplay:!0});if(n&&window.historyService){n.on("video:timeupdate",()=>{const c=n.currentTime,m=n.duration;c>0&&m>0&&Math.floor(c)%5===0&&window.historyService.addToHistory(s.video,{currentTime:c,duration:m,percentage:c/m*100,episode:s.currentEpisode})});const d=window.historyService.getHistory().find(c=>c.slug===s.video.slug);d&&d.progress&&d.progress.episode===s.currentEpisode&&d.progress.currentTime>0&&d.progress.percentage<95&&n.once("video:canplay",()=>{n.currentTime=d.progress.currentTime})}}}function A(e){t.videoPlayer.innerHTML=`
<div class="video-theater__loading">
<p>Error loading video: ${e}</p>
<button class="action-btn action-btn--primary" onclick="location.reload()">Retry</button>
</div>
`}function E(e,i=!1){if(!t.castCarousel)return;const r=e.slice(0,10);i?t.castCarousel.innerHTML=r.map(o=>{const n=o.profile_photo&&!o.profile_photo.includes("ui-avatars.com"),l=o.profile_photo||"",d=`/?search=${encodeURIComponent(o.name)}`,c=o.name.split(" ").map(m=>m[0]).join("").toUpperCase().slice(0,2);return`
<a href="${d}" class="flex-none w-28 group text-center snap-start">
<div class="size-20 mx-auto rounded-full overflow-hidden bg-surface-dark border-2 border-transparent group-hover:border-primary transition-all">
${n?`<img src="${l}" alt="${o.name}" class="w-full h-full object-cover" loading="lazy">`:`<div class="w-full h-full flex items-center justify-center text-2xl font-bold text-gray-400">${c}</div>`}
</div>
<p class="text-white text-sm font-medium mt-2 truncate group-hover:text-primary transition-colors">${o.name}</p>
<p class="text-gray-400 text-xs truncate">${o.character||"Actor"}</p>
</a>
`}).join(""):t.castCarousel.innerHTML=r.map(o=>{const n=`/?search=${encodeURIComponent(o)}`,l=o.split(" ").map(d=>d[0]).join("").toUpperCase().slice(0,2);return`
<a href="${n}" class="flex-none w-28 group text-center snap-start">
<div class="size-20 mx-auto rounded-full overflow-hidden bg-surface-dark border-2 border-transparent group-hover:border-primary transition-all flex items-center justify-center">
<span class="text-2xl font-bold text-gray-400">${l}</span>
</div>
<p class="text-white text-sm font-medium mt-2 truncate group-hover:text-primary transition-colors">${o}</p>
<p class="text-gray-400 text-xs truncate">Actor</p>
</a>
`}).join("")}async function j(){const e=t.recommendationsContainer;if(e)try{e.innerHTML='<div class="flex justify-center py-12"><div class="loading-spinner"></div></div>';const i=s.video;if(!i)return;const r=i.slug,o=new Set([r]),n=i.category?Object.values(i.category):i.genres||[],l=i.country?Object.values(i.country):i.countries||[],d=i.year,c=[];if(n.length>0){let a="";typeof n[0]=="object"&&n[0].slug?a=n[0].slug:typeof n[0]=="string"&&(a=n[0].toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d").replace(/\s+/g,"-")),a&&c.push(h.getRophimCatalog({page:1,limit:24,category:`the-loai/${a}`}).then(y=>({title:"More Like This",movies:y.movies||[]})).catch(()=>null))}if(l.length>0){let a="";typeof l[0]=="object"&&l[0].slug?a=l[0].slug:typeof l[0]=="string"&&(a=l[0].toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/đ/g,"d").replace(/\s+/g,"-")),a&&c.push(h.getRophimCatalog({page:1,limit:24,category:`quoc-gia/${a}`}).then(y=>({title:`Movies from ${l[0].name||l[0]}`,movies:y.movies||[]})).catch(()=>null))}d&&c.push(h.getRophimCatalog({page:1,limit:24,category:`nam-phat-hanh/${d}`}).then(a=>({title:`Released in ${d}`,movies:a.movies||[]})).catch(()=>null));const m=await Promise.all(c);e.innerHTML="";const u=new Set;let p=!1;m.forEach(a=>{if(!a||!a.movies||a.movies.length===0||a.title&&u.has(a.title))return;a.title&&u.add(a.title);const y=a.movies.filter(f=>!o.has(f.slug));if(y.forEach(f=>o.add(f.slug)),y.length===0)return;p=!0;const g=`
<div class="space-y-4">
${a.title?`<h4 class="text-md font-bold text-gray-300 pl-4 md:pl-0 border-l-2 border-primary md:border-none md:pl-0 leading-none h-5 flex items-center md:block">${a.title}</h4>`:""}
<div class="grid grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-8 gap-3">
${y.map(f=>N(f)).join("")}
</div>
</div>
`;e.insertAdjacentHTML("beforeend",g)}),p||(e.innerHTML='<p class="text-gray-400 text-center py-8">No specific recommendations found.</p>')}catch(i){console.error("Failed to load recommendations:",i),e.innerHTML='<p class="text-gray-400 text-center py-8">Failed to load recommendations</p>'}}function N(e){const i=e.poster_url||e.thumbnail||e.thumb_url||"",r=e.name||e.title||"Untitled",o=e.year||"",n=e.quality||"HD",l=e.matchScore||Math.floor(Math.random()*15+85),d=e.tmdb_rating||0,c=Math.round(d*10);return`
<div class="flex-none w-full cursor-pointer group relative transition-all duration-300 hover:z-30 hover:scale-105" onclick="window.location.href='/watch.html?id=${e.slug||e.id||""}'">
<div class="relative aspect-[2/3] rounded-md overflow-hidden bg-surface-dark shadow-sm group-hover:shadow-lg ring-0 group-hover:ring-2 group-hover:ring-white/20">
<div class="absolute inset-0 bg-cover bg-center transition-transform duration-500 group-hover:scale-110" style="background-image: url('${i}');"></div>
<!-- Gradient Overlay -->
<div class="absolute inset-0 bg-gradient-to-t from-black/80 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
<!-- Badges -->
<div class="absolute top-2 left-2 flex flex-col gap-1 z-20">
${o==new Date().getFullYear()?'<span class="bg-primary text-white text-[8px] font-bold px-1.5 py-0.5 rounded shadow">NEW</span>':""}
<span class="bg-black/60 backdrop-blur-md text-white text-[8px] font-bold px-1.5 py-0.5 rounded border border-white/10 uppercase">${n.replace("FHD","HD")}</span>
</div>
<!-- Content Overlay -->
<div class="absolute inset-0 z-20 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex flex-col justify-end p-2 pointer-events-none">
<div class="flex items-center gap-1 mb-1 pointer-events-auto">
<button class="bg-white text-black size-6 rounded-full flex items-center justify-center hover:scale-110 transition-transform">
<span class="material-symbols-outlined text-[16px]">play_arrow</span>
</button>
<button class="bg-black/60 border border-gray-400 text-white size-6 rounded-full flex items-center justify-center hover:bg-zinc-700 transition-transform">
<span class="material-symbols-outlined text-[14px]">add</span>
</button>
</div>
<h3 class="text-xs font-bold text-white line-clamp-1 mb-0.5 drop-shadow-md">${r}</h3>
<div class="flex items-center gap-1.5 text-[9px] text-gray-300 font-medium">
<span class="text-[#46d369] font-bold">${l}% Match</span>
<div class="flex items-center gap-1">
<span class="bg-[#FA320A] text-white px-1 rounded flex items-center gap-0.5 h-3">
<span class="material-symbols-outlined text-[8px]">local_pizza</span> ${c}%
</span>
</div>
</div>
</div>
</div>
</div>
`}function B(e){document.body.innerHTML=`
<div class="min-h-screen flex flex-col items-center justify-center text-white gap-6 p-4">
<span class="material-symbols-outlined text-6xl text-primary">error</span>
<h1 class="text-2xl font-bold">${e}</h1>
<a href="/" class="bg-primary text-white px-6 py-2 rounded font-medium hover:bg-primary/90 transition-colors">Go Home</a>
</div>
`}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",w):w();