function decodeHtmlEntities(text) { const map = { ''': "'", '"': '"', '&': '&', '<': '<', '>': '>', ''': "'", '/': '/', '`': '`', '=': '=', }; return text.replace(/&#?\w+;/g, (entity) => map[entity] || entity); } async function searchContent(keyword) { const results = []; const pages = [0, 2, 3, 4, 5]; try { const promises = pages.map(page => { const url = page === 0 ? `https://mangapark.net/search?word=${encodeURIComponent(keyword)}` : `https://mangapark.net/search?word=${encodeURIComponent(keyword)}&page=${page}`; return fetch(url) .then(response => response.text()) .then(html => { const regex = /]*>[\s\S]*?]*?title="([^"]+)"/g; const pageResults = []; let match; while ((match = regex.exec(html)) !== null) { pageResults.push({ id: "https://mangapark.net" + match[1].trim(), imageURL: "https://mangapark.net" + match[2].trim(), title: decodeHtmlEntities(match[3].trim()) }); } return pageResults; }) .catch(() => []); }); const allResults = await Promise.all(promises); return allResults.flat(); } catch (err) { return []; } } async function getContentData(url) { try { const response = await fetch(url); const html = await response.text(); const descRegex = /
([\s\S]*?)<\/div>/; const descMatch = html.match(descRegex); let description = descMatch ? descMatch[1].trim() : ""; description = description.replace(//g, '\n').replace(/<[^>]+>/g, ''); const tagsRegex = //g; const tags = []; let tagMatch; while ((tagMatch = tagsRegex.exec(html)) !== null) { tags.push(tagMatch[1].trim()); } return { description, tags }; } catch (err) { return { description: "Error", tags: [] }; } } async function getChapters(url) { const results = []; try { const response = await fetch(url); const html = await response.text(); const regex = /]*class="link-hover link-primary[^"]*"[^>]*>([^<]+)<\/a>/g; let match; while ((match = regex.exec(html)) !== null) { const href = match[1]; const title = match[2].trim(); let chapterNum = null; let chapterMatch = title.match(/Chapter\s+([\d.]+)/i); if (chapterMatch) { chapterNum = parseFloat(chapterMatch[1]); } else { chapterMatch = title.match(/Ch\.([\d.]+)/i); if (chapterMatch) { chapterNum = parseFloat(chapterMatch[1]); } } if (chapterNum === null) continue; results.push([ String(chapterNum), [{ id: "https://mangapark.net" + href, title: title, chapter: chapterNum, scanlation_group: title }] ]); } results.sort((a, b) => parseFloat(a[0]) - parseFloat(b[0])); return { en: results }; } catch (err) { console.error('Error fetching chapters:', err); return { en: [] }; } } async function getChapterImages(url) { const results = []; try { const response = await fetch(url); const html = await response.text(); const jsonMatch = html.match(/