// // // Main functions // // async function searchResults(query) { const encodeQuery = keyword => encodeURIComponent(keyword); const decodeHtmlEntities = (str) => { if (!str) return str; return str.replace(/&#(\d+);/g, (match, dec) => String.fromCharCode(dec)) .replace(/"/g, '"') .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>'); }; const fuzzyMatch = (query, title) => { const q = query.toLowerCase().trim(); const t = title.toLowerCase().trim(); if (t === q) return 1000; if (t.includes(q)) return 900; const qTokens = q.split(/\s+/).filter(token => token.length > 0); const tTokens = t.split(/[\s\-]+/).filter(token => token.length > 0); const stopwords = new Set(['the', 'a', 'an', 'and', 'or', 'of', 'in', 'on', 'at', 'to', 'for']); let score = 0; let matchedTokens = 0; let significantMatches = 0; qTokens.forEach(qToken => { const isStopword = stopwords.has(qToken); let bestMatch = 0; tTokens.forEach(tToken => { let matchScore = 0; if (tToken === qToken) { matchScore = isStopword ? 20 : 100; if (!isStopword) significantMatches++; } else if (tToken.includes(qToken) && qToken.length >= 3) { matchScore = isStopword ? 10 : 60; if (!isStopword) significantMatches++; } else if (qToken.includes(tToken) && tToken.length >= 3) { matchScore = isStopword ? 10 : 50; if (!isStopword) significantMatches++; } else if (qToken.length >= 3 && tToken.length >= 3) { const dist = levenshteinDistance(qToken, tToken); const maxLen = Math.max(qToken.length, tToken.length); const similarity = 1 - (dist / maxLen); if (similarity > 0.7) { matchScore = Math.floor(similarity * 40); if (!isStopword) significantMatches++; } } bestMatch = Math.max(bestMatch, matchScore); }); if (bestMatch > 0) { score += bestMatch; matchedTokens++; } }); const significantTokens = qTokens.filter(t => !stopwords.has(t)).length; const requiredMatches = Math.ceil(significantTokens * 0.7); if (significantMatches < requiredMatches) { return 0; } if (matchedTokens >= qTokens.length) { score += 100; } if (t.startsWith(q)) { score += 150; } const extraWords = tTokens.length - qTokens.length; if (extraWords > 3) { score -= (extraWords - 3) * 20; } for (let i = 0; i < qTokens.length - 1; i++) { const bigram = qTokens[i] + ' ' + qTokens[i + 1]; const bigramNoDash = qTokens[i] + qTokens[i + 1]; if (!t.includes(bigram) && !t.includes(bigramNoDash)) { score -= 15; } } return Math.max(0, score); }; const levenshteinDistance = (a, b) => { const matrix = []; for (let i = 0; i <= b.length; i++) { matrix[i] = [i]; } for (let j = 0; j <= a.length; j++) { matrix[0][j] = j; } for (let i = 1; i <= b.length; i++) { for (let j = 1; j <= a.length; j++) { if (b.charAt(i - 1) === a.charAt(j - 1)) { matrix[i][j] = matrix[i - 1][j - 1]; } else { matrix[i][j] = Math.min( matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1 ); } } } return matrix[b.length][a.length]; }; const animekaiSearch = async () => { const searchBaseUrl = "https://animekai.to/browser?keyword="; const baseUrl = "https://animekai.to"; const posterHrefRegex = /href="[^"]*" class="poster"/g; const titleRegex = /class="title"[^>]*title="[^"]*"/g; const imageRegex = /data-src="[^"]*"/g; const extractHrefRegex = /href="([^"]*)"/; const extractImageRegex = /data-src="([^"]*)"/; const extractTitleRegex = /title="([^"]*)"/; const extractResultsFromHTML = (htmlText) => { const results = []; const posterMatches = htmlText.match(posterHrefRegex) || []; const titleMatches = htmlText.match(titleRegex) || []; const imageMatches = htmlText.match(imageRegex) || []; const minLength = Math.min(posterMatches.length, titleMatches.length, imageMatches.length); for (let i = 0; i < minLength; i++) { const hrefMatch = posterMatches[i].match(extractHrefRegex); const fullHref = hrefMatch ? (hrefMatch[1].startsWith("http") ? hrefMatch[1] : baseUrl + hrefMatch[1]) : null; const imageMatch = imageMatches[i].match(extractImageRegex); const imageSrc = imageMatch ? imageMatch[1] : null; const titleMatch = titleMatches[i].match(extractTitleRegex); const cleanTitle = titleMatch ? decodeHtmlEntities(titleMatch[1]) : null; if (fullHref && imageSrc && cleanTitle) { results.push({ href: `Animekai:${fullHref}`, image: imageSrc, title: cleanTitle }); } } return results; }; try { const encodedQuery = encodeQuery(query); const urls = [ `${searchBaseUrl}${encodedQuery}`, `${searchBaseUrl}${encodedQuery}&page=2`, `${searchBaseUrl}${encodedQuery}&page=3` ]; const responses = await Promise.all(urls.map(url => fetchv2(url))); const htmlTexts = await Promise.all(responses.map(res => res.text())); const allResults = []; htmlTexts.forEach(html => allResults.push(...extractResultsFromHTML(html))); return allResults; } catch (error) { console.error("Animekai search error:" + error); return []; } }; const oneMoviesSearch = async () => { const searchBaseUrl = "https://1movies.bz/browser?keyword="; const baseUrl = "https://1movies.bz"; const posterHrefRegex = /href="([^"]*)" class="poster"/g; const titleRegex = /class="title" href="[^"]*">([^<]*) { const results = []; const posterMatches = [...htmlText.matchAll(posterHrefRegex)]; const titleMatches = [...htmlText.matchAll(titleRegex)]; const imageMatches = [...htmlText.matchAll(imageRegex)]; const minLength = Math.min(posterMatches.length, titleMatches.length, imageMatches.length); for (let i = 0; i < minLength; i++) { const href = posterMatches[i][1]; const fullHref = href.startsWith("http") ? href : baseUrl + href; const imageSrc = imageMatches[i][1]; const title = decodeHtmlEntities(titleMatches[i][1]); results.push({ href: fullHref, image: imageSrc, title }); } return results; }; try { const encodedQuery = encodeQuery(query); const urls = [ `${searchBaseUrl}${encodedQuery}`, `${searchBaseUrl}${encodedQuery}&page=2`, `${searchBaseUrl}${encodedQuery}&page=3` ]; const responses = await Promise.all(urls.map(url => fetchv2(url))); const htmlTexts = await Promise.all(responses.map(res => res.text())); const allResults = []; htmlTexts.forEach(html => allResults.push(...extractResultsFromHTML(html))); return allResults; } catch (error) { console.error("1Movies search error:" + error); return []; } }; try { const [animekaiResults, oneMoviesResults] = await Promise.all([ animekaiSearch(), oneMoviesSearch() ]); const mergedResults = [...animekaiResults, ...oneMoviesResults]; const scoredResults = mergedResults.map(r => ({ ...r, score: fuzzyMatch(query, r.title) })); const filteredResults = scoredResults .filter(r => r.score > 0) .sort((a, b) => b.score - a.score) .map(({ score, ...rest }) => rest); return JSON.stringify(filteredResults.length > 0 ? filteredResults : [{ href: "", image: "", title: "No results found, please refine query." }]); } catch (error) { return JSON.stringify([{ href: "", image: "", title: "Search failed: " + error.message }]); } } async function extractDetails(url) { if (url.startsWith("Animekai:")) { const actualUrl = url.replace("Animekai:", "").trim(); try { const response = await fetchv2(actualUrl); const htmlText = await response.text(); const descriptionMatch = (/
([\s\S]*?)<\/div>/.exec(htmlText) || [])[1]; const aliasesMatch = (/([\s\S]*?)<\/small>/.exec(htmlText) || [])[1]; return JSON.stringify([{ description: descriptionMatch ? cleanHtmlSymbols(descriptionMatch) : "Not available", aliases: aliasesMatch ? cleanHtmlSymbols(aliasesMatch) : "Not available", airdate: "If stream doesn't load try later or disable VPN/DNS" }]); } catch (error) { console.error("Error fetching Animekai details:" + error); return JSON.stringify([{ description: "Error loading description", aliases: "Aliases: Unknown", airdate: "Aired: Unknown" }]); } } else { try { const response = await fetchv2(url); const htmlText = await response.text(); const descriptionMatch = (/
([\s\S]*?)<\/div>/.exec(htmlText) || [])[1]; const aliasesMatch = (/([\s\S]*?)<\/small>/.exec(htmlText) || [])[1]; const airdateMatch = (/
  • Released:\s*]*>(.*?)<\/span>/.exec(htmlText) || [])[1]; return JSON.stringify([{ description: descriptionMatch ? cleanHtmlSymbols(descriptionMatch) : "Not available", aliases: aliasesMatch ? cleanHtmlSymbols(aliasesMatch) : "Not aliases", airdate: airdateMatch ? cleanHtmlSymbols(airdateMatch) : "Not available" }]); } catch (error) { console.error("Error fetching 1Movies details:"+ error); return JSON.stringify([{ description: "Error loading description", aliases: "Not available", airdate: "Not available" }]); } } } async function extractEpisodes(url) { const sendEpisodes = async (endpoint, episodeData) => { if (episodeData.length > 45) { const promises = episodeData.map(item => fetchv2(`${endpoint}=${encodeURIComponent(item.data)}`) .then(res => res.text()) .then(data => ({ name: item.name, data })) .catch(err => ({ name: item.name, error: err.toString() })) ); return Promise.all(promises); } else { const resp = await fetchv2(endpoint, {}, "POST", JSON.stringify(episodeData)); return resp.json(); } }; try { if (url.startsWith("Animekai:")) { const actualUrl = url.replace("Animekai:", "").trim(); const htmlText = await (await fetchv2(actualUrl)).text(); const animeIdMatch = (htmlText.match(/
    ]*data-id="([^"]+)"/) || [])[1]; if (!animeIdMatch) return JSON.stringify([{ error: "AniID not found" }]); const tokenResponse = await fetchv2(`https://ilovekai.simplepostrequest.workers.dev/?ilovefeet=${encodeURIComponent(animeIdMatch)}`); const token = await tokenResponse.text(); const episodeListUrl = `https://animekai.to/ajax/episodes/list?ani_id=${animeIdMatch}&_=${token}`; const episodeListData = await (await fetchv2(episodeListUrl)).json(); const cleanedHtml = cleanJsonHtml(episodeListData.result); const episodeRegex = /]+num="([^"]+)"[^>]+token="([^"]+)"[^>]*>/g; const episodeMatches = [...cleanedHtml.matchAll(episodeRegex)]; const episodeData = episodeMatches.map(([_, episodeNum, episodeToken]) => ({ name: `Episode ${episodeNum}`, data: episodeToken })); const batchResults = await sendEpisodes("https://ilovekai.simplepostrequest.workers.dev/?ilovefeet", episodeData); const episodes = batchResults.map((result, index) => ({ number: parseInt(episodeMatches[index][1], 10), href: `Animekai:https://animekai.to/ajax/links/list?token=${episodeMatches[index][2]}&_=${result.data}` })); return JSON.stringify(episodes); } else { const htmlText = await (await fetchv2(url)).text(); const movieIDMatch = (htmlText.match(/
    ]*id="movie-rating"[^>]*data-id="([^"]+)"/) || [])[1]; if (!movieIDMatch) return JSON.stringify([{ error: "MovieID not found" }]); const movieData = [{ name: "MovieID", data: movieIDMatch }]; const tokenResponse = await fetchv2("https://ilovekai.simplepostrequest.workers.dev/ilovethighs", {}, "POST", JSON.stringify(movieData)); const temp = await tokenResponse.json(); const token = temp[0]?.data; const episodeListUrl = `https://1movies.bz/ajax/episodes/list?id=${movieIDMatch}&_=${token}`; const episodeListData = await (await fetchv2(episodeListUrl)).json(); const cleanedHtml = cleanJsonHtml(episodeListData.result); const episodeRegex = /]+eid="([^"]+)"[^>]+num="([^"]+)"[^>]*>/g; const episodeMatches = [...cleanedHtml.matchAll(episodeRegex)]; const episodeData = episodeMatches.map(([_, episodeToken, episodeNum]) => ({ name: `Episode ${episodeNum}`, data: episodeToken })); const batchResults = await sendEpisodes("https://ilovekai.simplepostrequest.workers.dev/?ilovethighs", episodeData); const episodes = batchResults.map((result, index) => ({ number: parseInt(episodeMatches[index][2], 10), href: `https://1movies.bz/ajax/links/list?eid=${episodeMatches[index][1]}&_=${result.data}` })); return JSON.stringify(episodes); } } catch (err) { console.error("Error fetching episodes:" + err); return JSON.stringify([{ number: 1, href: "Error fetching episodes" }]); } } async function extractStreamUrl(url) { let source, actualUrl; if (url.startsWith("Animekai:")) { source = "Animekai"; actualUrl = url.replace("Animekai:", "").trim(); } else if (url.includes("1movies.bz")) { source = "1Movies"; actualUrl = url.trim(); } else { console.log("Failed to match URL:", url); return "Invalid URL format: " + url; } if (source === "Animekai") { try { const response = await fetchv2(actualUrl); const text = await response.text(); const cleanedHtml = cleanJsonHtml(text); const subRegex = /
    ]*>([\s\S]*?)<\/div>/; const softsubRegex = /
    ]*>([\s\S]*?)<\/div>/; const dubRegex = /
    ]*>([\s\S]*?)<\/div>/; const subMatch = subRegex.exec(cleanedHtml); const softsubMatch = softsubRegex.exec(cleanedHtml); const dubMatch = dubRegex.exec(cleanedHtml); const subContent = subMatch ? subMatch[1].trim() : ""; const softsubContent = softsubMatch ? softsubMatch[1].trim() : ""; const dubContent = dubMatch ? dubMatch[1].trim() : ""; const serverSpanRegex = /]*data-lid="([^"]+)"[^>]*>Server 1<\/span>/; const serverIdDub = serverSpanRegex.exec(dubContent)?.[1]; const serverIdSoftsub = serverSpanRegex.exec(softsubContent)?.[1]; const serverIdSub = serverSpanRegex.exec(subContent)?.[1]; const tokenRequestData = [ { name: "Dub", data: serverIdDub }, { name: "Softsub", data: serverIdSoftsub }, { name: "Sub", data: serverIdSub } ].filter(item => item.data); const tokenBatchResponse = await fetchv2( "https://ilovekai.simplepostrequest.workers.dev/?ilovefeet", {}, "POST", JSON.stringify(tokenRequestData) ); const tokenResults = await tokenBatchResponse.json(); const streamUrls = tokenResults.map(result => { const serverIdMap = { "Dub": serverIdDub, "Softsub": serverIdSoftsub, "Sub": serverIdSub }; return { type: result.name, url: `https://animekai.to/ajax/links/view?id=${serverIdMap[result.name]}&_=${result.data}` }; }); const processStreams = async (streamUrls) => { const streamResponses = await Promise.all( streamUrls.map(async ({ type, url }) => { try { const res = await fetchv2(url); const json = await res.json(); return { type: type, result: json.result }; } catch (error) { console.log(`Error fetching ${type} stream:` + error); return { type: type, result: null }; } }) ); const decryptRequestData = streamResponses .filter(item => item.result) .map(item => ({ name: item.type, data: item.result })); if (decryptRequestData.length === 0) { return {}; } const decryptBatchResponse = await fetchv2( "https://ilovekai.simplepostrequest.workers.dev/?ilovearmpits", {}, "POST", JSON.stringify(decryptRequestData) ); const decryptResults = await decryptBatchResponse.json(); const finalResults = {}; decryptResults.forEach(result => { try { const parsed = JSON.parse(result.data); finalResults[result.name] = parsed.url; console.log(`decrypted${result.name} URL:` + parsed.url); } catch (error) { console.log(`Error parsing ${result.name} result:` + error); finalResults[result.name] = null; } }); return finalResults; }; const decryptedUrls = await processStreams(streamUrls); const decryptedSub = decryptedUrls.Sub; const decryptedDub = decryptedUrls.Dub; const decryptedRaw = decryptedUrls.Softsub; const headers = { "Referer": "https://animekai.to/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" }; async function getStream(url) { try { const response = await fetchv2(url.replace("/e/", "/media/"), headers); const responseJson = await response.json(); const result = responseJson?.result; const postData = { "text": result, "Useragent": headers["User-Agent"] }; const finalResponse = await fetchv2( "https://ilovekai.simplepostrequest.workers.dev/ilovebush", {}, "POST", JSON.stringify(postData) ); const finalJson = await finalResponse.json(); return finalJson?.result?.sources?.[0]?.file || null; } catch { return null; } } const streams = []; const subStream = decryptedSub ? await getStream(decryptedSub) : null; if (subStream) streams.push("Hardsub English", subStream); const dubStream = decryptedDub ? await getStream(decryptedDub) : null; if (dubStream) streams.push("Dubbed English", dubStream); const rawStream = decryptedRaw ? await getStream(decryptedRaw) : null; if (rawStream) streams.push("Japanese", rawStream); const final = { streams, subtitles: "" }; console.log("RETURN: " + JSON.stringify(final)); return JSON.stringify(final); } catch (error) { console.log("Animekai fetch error:" + error); return "https://error.org"; } } else if (source === "1Movies") { try { const response = await fetchv2(actualUrl); const responseData = await response.json(); const cleanedHtml = cleanJsonHtml(responseData.result); const server1Regex = /
    ]*data-lid="([^"]+)"[^>]*>\s*Server 1<\/span>/; const server1Match = server1Regex.exec(cleanedHtml); if (!server1Match) { console.log("Server 1 not found"); return "error"; } const serverId = server1Match[1]; const tokenRequestData = [{ name: "Server1", data: serverId }]; const tokenBatchResponse = await fetchv2( "https://ilovekai.simplepostrequest.workers.dev/ilovethighs", {}, "POST", JSON.stringify(tokenRequestData) ); const tokenResults = await tokenBatchResponse.json(); const token = tokenResults[0]?.data; if (!token) { console.log("Token not found"); return "error"; } const streamUrl = `https://1movies.bz/ajax/links/view?id=${serverId}&_=${token}`; const streamResponse = await fetchv2(streamUrl); const streamData = await streamResponse.json(); if (!streamData.result) { console.log("Stream result not found"); return "error"; } const decryptRequestData = [{ name: "Server1", data: streamData.result }]; const decryptBatchResponse = await fetchv2( "https://ilovekai.simplepostrequest.workers.dev/iloveboobs", {}, "POST", JSON.stringify(decryptRequestData) ); const decryptedResponse = await decryptBatchResponse.json(); const decryptedUrl = decryptedResponse[0]?.data.url; const subListEncoded = decryptedUrl.split("sub.list=")[1]?.split("&")[0]; const subListUrl = decodeURIComponent(subListEncoded); const subResponse = await fetchv2(subListUrl); const subtitles = await subResponse.json(); const englishSubUrl = subtitles.find(sub => sub.label === "English")?.file.replace(/\\\//g, "/"); if (!decryptedUrl) { console.log("Decryption failed"); return "error"; } const headers = { "Referer": "https://1movies.bz/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" }; const mediaResponse = await fetchv2(decryptedUrl.replace("/e/", "/media/"), headers); const mediaJson = await mediaResponse.json(); const result = mediaJson?.result; if (!result) { console.log("Media result not found"); return "error"; } const postData = { "text": result, "Useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36" }; const finalResponse = await fetchv2("https://ilovekai.simplepostrequest.workers.dev/iloveass", {}, "POST", JSON.stringify(postData)); const finalJson = await finalResponse.json(); const m3u8Link = finalJson?.result?.sources?.[0]?.file; const returnValue = { stream: m3u8Link, subtitles: englishSubUrl }; return JSON.stringify(returnValue); } catch (error) { console.log("1Movies fetch error:" + error); return "https://error.org"; } } } /// /// /// Helper functions /// /// function cleanHtmlSymbols(string) { if (!string) { return ""; } return string .replace(/’/g, "'") .replace(/–/g, "-") .replace(/&#[0-9]+;/g, "") .replace(/\r?\n|\r/g, " ") .replace(/\s+/g, " ") .trim(); } function cleanJsonHtml(jsonHtml) { if (!jsonHtml) { return ""; } return jsonHtml .replace(/\\"/g, "\"") .replace(/\\'/g, "'") .replace(/\\\\/g, "\\") .replace(/\\n/g, "\n") .replace(/\\t/g, "\t") .replace(/\\r/g, "\r"); } function decodeHtmlEntities(text) { if (!text) { return ""; } return text .replace(/'/g, "'") .replace(/"/g, "\"") .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/ /g, " "); }