async function searchResults(keyword) { const results = []; const headers = { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest" }; const regex = /background-image:\s*url\("([^"]+)"\)[^]*?

]*>\s*([^<]+)/g; const postData = `action=ajaxsearchlite_search&aslp=${keyword}&asid=1&options=qtranslate_lang%3D0%26set_intitle%3DNone%26set_incontent%3DNone%26set_inexcerpt%3DNone%26set_inpages%3DNone`; try { const response = await fetchv2("https://www.mavanimes.co/wp-admin/admin-ajax.php", headers, "POST", postData); const html = await response.text(); let match; while ((match = regex.exec(html)) !== null) { results.push({ title: match[3].trim(), image: match[1].trim(), href: match[2].trim() }); } return JSON.stringify(results); } catch (err) { return JSON.stringify([{ title: "Error", image: "Error", href: "Error" }]); } } async function extractDetails(url) { try { return JSON.stringify([{ description: "Désolé, le format des données est incohérent, impossible d’extraire de manière fiable.", aliases: "N/A", airdate: "N/A" }]); } catch (err) { return JSON.stringify([{ description: "Error", aliases: "Error", airdate: "Error" }]); } } async function extractEpisodes(url) { const results = []; const regex = /]*>\s*/gi; try { const response = await fetchv2(url); const html = await response.text(); let match; let count = 1; while ((match = regex.exec(html)) !== null) { results.push({ href: match[1].trim(), number: count }); count++; } results.forEach((item, i) => { item.number = results.length - i; }); return JSON.stringify(results.reverse()); } catch (err) { return JSON.stringify([{ href: "Error", number: "Error" }]); } } async function extractStreamUrl(url) { try { const response = await fetchv2(url); const html = await response.text(); const voeMatch = html.match(/https:\/\/voe\.sx\/e\/[a-zA-Z0-9]+/); if (!voeMatch) return null; const voeLink = voeMatch[0]; const voeResponse = await fetchv2(voeLink); const voeHtml = await voeResponse.text(); const redirectMatch = voeHtml.match(/window\.location\.href\s*=\s*['"]([^'"]+)['"]/); if (!redirectMatch) return null; const finalLink = redirectMatch[1]; const streamUrlOne = finalLink; const responseTwo = await fetchv2(streamUrlOne); const finalHtml = await responseTwo.text(); let streamUrl = null; try { streamUrl = voeExtractor(finalHtml); } catch (error) { console.log("VOE extraction error:", error); return null; } console.log("Voe Stream URL: " + streamUrl); return streamUrl; } catch (error) { console.log("Extract stream URL error:", error); return null; } } /* SCHEME START */ /** * @name voeExtractor * @author Cufiy */ function voeExtractor(html, url = null) { // Extract the first const jsonScriptMatch = html.match( /]+type=["']application\/json["'][^>]*>([\s\S]*?)<\/script>/i ); if (!jsonScriptMatch) { console.log("No application/json script tag found"); return null; } const obfuscatedJson = jsonScriptMatch[1].trim(); let data; try { data = JSON.parse(obfuscatedJson); } catch (e) { throw new Error("Invalid JSON input."); } if (!Array.isArray(data) || typeof data[0] !== "string") { throw new Error("Input doesn't match expected format."); } let obfuscatedString = data[0]; // Step 1: ROT13 let step1 = voeRot13(obfuscatedString); // Step 2: Remove patterns let step2 = voeRemovePatterns(step1); // Step 3: Base64 decode let step3 = voeBase64Decode(step2); // Step 4: Subtract 3 from each char code let step4 = voeShiftChars(step3, 3); // Step 5: Reverse string let step5 = step4.split("").reverse().join(""); // Step 6: Base64 decode again let step6 = voeBase64Decode(step5); // Step 7: Parse as JSON let result; try { result = JSON.parse(step6); } catch (e) { throw new Error("Final JSON parse error: " + e.message); } // console.log("Decoded JSON:", result); // check if direct_access_url is set, not null and starts with http if (result && typeof result === "object") { const streamUrl = result.direct_access_url || result.source .map((source) => source.direct_access_url) .find((url) => url && url.startsWith("http")); if (streamUrl) { console.log("Voe Stream URL: " + streamUrl); return streamUrl; } else { console.log("No stream URL found in the decoded JSON"); } } return result; } function voeRot13(str) { return str.replace(/[a-zA-Z]/g, function (c) { return String.fromCharCode( (c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26 ); }); } function voeRemovePatterns(str) { const patterns = ["@$", "^^", "~@", "%?", "*~", "!!", "#&"]; let result = str; for (const pat of patterns) { result = result.split(pat).join(""); } return result; } function voeBase64Decode(str) { // atob is available in browsers and Node >= 16 if (typeof atob === "function") { return atob(str); } // Node.js fallback return Buffer.from(str, "base64").toString("utf-8"); } function voeShiftChars(str, shift) { return str .split("") .map((c) => String.fromCharCode(c.charCodeAt(0) - shift)) .join(""); } /* SCHEME END */