class asmhentai { constructor() { this.baseUrl = "https://asmhentai.com"; this.type = "book-board"; this.mediaType = "manga"; } async search(queryObj) { const q = (queryObj.query || "").trim().replace(/\s+/g, "+"); const html = await fetch(`${this.baseUrl}/search/?q=${q}&page=1`).then(r => r.text()); const $ = this.cheerio.load(html); const results = []; $(".preview_item").each((_, el) => { const href = $(el).find(".image a").attr("href"); const id = href?.match(/\/g\/(\d+)\//)?.[1]; if (!id) return; let img = $(el).find(".image img").attr("data-src") || $(el).find(".image img").attr("src") || ""; if (img.startsWith("//")) img = "https:" + img; const image = img.replace("thumb.jpg", "1.jpg"); const title = $(el).find("h2.caption").text().trim(); results.push({ id, image, title, rating: null, type: "book" }); }); return results; } async getMetadata(id) { const html = await fetch(`${this.baseUrl}/g/${id}/`).then(r => r.text()); const $ = this.cheerio.load(html); let image = $('a[href^="/gallery/"] img').attr("data-src") || $('a[href^="/gallery/"] img').attr("src") || ""; if (image.startsWith("//")) image = "https:" + image; const genres = $(".tags .tag_list .badge.tag") .map((_, el) => $(el).clone().children().remove().end().text().trim()) .get() .join(", "); return { id, title: $("h1").first().text().trim(), format: "MANGA", score: 0, genres, status: "unknown", published: "???", summary: "", chapters: 1, image }; } async findChapters(mangaId) { const html = await fetch(`${this.baseUrl}/g/${mangaId}/`).then(r => r.text()); const $ = this.cheerio.load(html); const title = $("h1").first().text().trim() || "Chapter 1"; let thumb = $(".gallery img").first().attr("data-src") || ""; if (thumb.startsWith("//")) thumb = "https:" + thumb; const base = thumb.match(/https:\/\/[^\/]+\/\d+\/\d+\//)?.[0]; const pages = parseInt($(".pages").text().match(/\d+/)?.[0] || "0"); const ext = thumb.match(/\.(jpg|png|jpeg|gif)/i)?.[1] || "jpg"; const chapterId = Buffer.from(JSON.stringify({ base, pages, ext })).toString("base64"); return [{ id: chapterId, title, number: 1, releaseDate: null, index: 0 }]; } async findChapterPages(chapterId) { const { base, pages, ext } = JSON.parse( Buffer.from(chapterId, "base64").toString("utf8") ); return Array.from({ length: pages }, (_, i) => ({ url: `${base}${i + 1}.${ext}`, index: i })); } } module.exports = asmhentai;