const MediaMetadataUtils = { getTitle(data) { if (!data) return "Unknown Title"; if (data.title) { if (typeof data.title === 'string') return data.title; return data.title.english || data.title.romaji || data.title.native || "Unknown Title"; } return data.name || "Unknown Title"; }, getDescription(data) { const rawDesc = data.description || data.summary || "No description available."; const tmp = document.createElement("DIV"); tmp.innerHTML = rawDesc; return tmp.textContent || tmp.innerText || rawDesc; }, getPosterUrl(data, isExtension = false) { if (isExtension) { return data.image || ''; } if (data.coverImage) { return data.coverImage.extraLarge || data.coverImage.large || data.coverImage.medium || ''; } return data.image || ''; }, getBannerUrl(data, isExtension = false) { if (isExtension) { return data.image || ''; } return data.bannerImage || this.getPosterUrl(data, isExtension); }, getScore(data, isExtension = false) { if (isExtension) { return data.score ? Math.round(data.score * 10) : '?'; } return data.averageScore || '?'; }, getYear(data, isExtension = false) { if (isExtension) { return data.year || data.published || '????'; } if (data.seasonYear) return data.seasonYear; if (data.startDate?.year) return data.startDate.year; return '????'; }, getGenres(data, maxGenres = 3) { if (!data.genres || !Array.isArray(data.genres)) return ''; return data.genres.slice(0, maxGenres).join(' • '); }, getSeason(data, isExtension = false) { if (isExtension) { return data.season || 'Unknown'; } if (data.season && data.seasonYear) { return `${data.season} ${data.seasonYear}`; } if (data.startDate?.year && data.startDate?.month) { const months = ['', 'Winter', 'Winter', 'Spring', 'Spring', 'Spring', 'Summer', 'Summer', 'Summer', 'Fall', 'Fall', 'Fall', 'Winter']; const season = months[data.startDate.month] || ''; return season ? `${season} ${data.startDate.year}` : `${data.startDate.year}`; } return 'Unknown'; }, getStudio(data, isExtension = false) { if (isExtension) { return data.studio || "Unknown"; } if (data.studios?.nodes?.[0]?.name) { return data.studios.nodes[0].name; } if (data.studios?.edges?.[0]?.node?.name) { return data.studios.edges[0].node.name; } return 'Unknown Studio'; }, getCharacters(data, isExtension = false, maxChars = 5) { let characters = []; if (isExtension) { characters = data.characters || []; } else { if (data.characters?.nodes?.length > 0) { characters = data.characters.nodes; } else if (data.characters?.edges?.length > 0) { characters = data.characters.edges .filter(edge => edge?.node?.name?.full) .map(edge => edge.node); } } return characters.slice(0, maxChars).map(char => ({ name: char?.name?.full || char?.name || "Unknown", image: char?.image?.large || char?.image?.medium || null })); }, getTotalEpisodes(data, isExtension = false) { if (isExtension) { return data.episodes || 1; } if (data.nextAiringEpisode?.episode) { return data.nextAiringEpisode.episode - 1; } return data.episodes || 12; }, truncateDescription(text, maxSentences = 4) { const tmp = document.createElement("DIV"); tmp.innerHTML = text; const cleanText = tmp.textContent || tmp.innerText || ""; const sentences = cleanText.match(/[^\.!\?]+[\.!\?]+/g) || [cleanText]; if (sentences.length > maxSentences) { return { short: sentences.slice(0, maxSentences).join(' ') + '...', full: text, isTruncated: true }; } return { short: text, full: text, isTruncated: false }; }, formatBookData(data, isExtension = false) { return { title: this.getTitle(data), description: this.getDescription(data), score: this.getScore(data, isExtension), year: this.getYear(data, isExtension), status: data.status || 'Unknown', format: data.format || (isExtension ? 'LN' : 'MANGA'), chapters: data.chapters || '?', volumes: data.volumes || '?', poster: this.getPosterUrl(data, isExtension), banner: this.getBannerUrl(data, isExtension), genres: this.getGenres(data) }; }, formatAnimeData(data, isExtension = false) { return { title: this.getTitle(data), description: this.getDescription(data), score: this.getScore(data, isExtension), year: this.getYear(data, isExtension), season: this.getSeason(data, isExtension), status: data.status || 'Unknown', format: data.format || 'TV', episodes: this.getTotalEpisodes(data, isExtension), poster: this.getPosterUrl(data, isExtension), banner: this.getBannerUrl(data, isExtension), genres: this.getGenres(data), studio: this.getStudio(data, isExtension), characters: this.getCharacters(data, isExtension), trailer: data.trailer || null }; } }; window.MediaMetadataUtils = MediaMetadataUtils;