qrtzcode
HomeDocsAPILeaderboardChangelog
Contribute
Docs

qrtzcode

Kumpulan gist & snippet pribadi — anime, AI tools, scraper, dan randomness.

Navigate

HomeDocsAPI Reference

Links

© 2026 qrtz. All snippets welcome.

ESC

Navigate

Links

Anime

oploverz

kalo ad bug benerin ajh sendiri.

Creator

qrtz

Language

javascript

Views

9

Copies

7

Base

https://vip.oploverz.ltd

Updated

24 Jun 2026

#anime#scraper

Code

97
oploverz.js
import axios from "axios";
import * as cheerio from "cheerio";
import fs from "fs";
import https from "https";

const BASE = "https://vip.oploverz.ltd";
const BACKAPI = "https://backapi.oploverz.ac/uploads/";
const TIMEOUT = 30000;
const MAX_RETRIES = 5;
const RETRY_DELAY = 1000;

const USER_AGENTS = [
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0",
  "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
  "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
  "Mozilla/5.0 (iPad; CPU OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Mobile/15E148 Safari/604.1",
  "Mozilla/5.0 (Android 14; Mobile; rv:133.0) Gecko/133.0 Firefox/133.0",
  "Mozilla/5.0 (Android 14; Mobile; wv) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 OPR/115.0.0.0",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Vivaldi/6.9.0.0",
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Vivaldi/6.8.0.0",
  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Vivaldi/6.9.0.0",
  "Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
  "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
];

function randomUA() {
  return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
}

function randomDelay(min = 100, max = 1500) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getHeaders() {
  const ua = randomUA();
  return {
    "User-Agent": ua,
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "Accept-Language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Cache-Control": "max-age=0",
    "Sec-Ch-Ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
    "Sec-Ch-Ua-Mobile": "?0",
    "Sec-Ch-Ua-Platform": '"Windows"',
    "Referer": "https://vip.oploverz.ltd/",
    "Origin": "https://vip.oploverz.ltd",
  };
}

const http = axios.create({
  baseURL: BASE,
  timeout: TIMEOUT,
  withCredentials: true,
  httpsAgent: new https.Agent({ rejectUnauthorized: false, keepAlive: true }),
});

const AD_DOMAINS = [
  "blogger.com", "blogspot.com", "paladindrama",
  "glamour", "mayhap", "histats",
  "slot", "casino", "mpo", "judol",
  "placehold.co", "comentario", "cloudflareinsights",
];

function isClean(url = "") {
  if (!url) return false;
  const lower = url.toLowerCase();
  return !AD_DOMAINS.some(d => lower.includes(d));
}

function decodeSvelteFlat(raw) {
  if (!raw || !Array.isArray(raw.nodes)) return null;
  const dataNode = raw.nodes.find(n => n?.type === "data" && Array.isArray(n.data));
  if (!dataNode) return null;
  const arr = dataNode.data;
  function resolve(idx) {
    if (idx === null || idx === undefined) return null;
    const val = arr[idx];
    if (val === null || val === undefined) return val;
    if (typeof val !== "object") return val;
    if (Array.isArray(val)) return val.map(i => resolve(i));
    const result = {};
    for (const [k, v] of Object.entries(val)) result[k] = resolve(v);
    return result;
  }
  return resolve(0);
}

async function fetchDataJson(path, referer, retries = MAX_RETRIES) {
  const endpoint = (path === "/" ? "" : path) + "/__data.json?x-sveltekit-invalidated=001";
  for (let i = 0; i < retries; i++) {
    try {
      const headers = getHeaders();
      headers.Referer = referer || BASE + "/";
      const res = await http.get(endpoint, { headers });
      if (res.status === 403 || res.status === 503) {
        throw new Error(`Blocked (${res.status})`);
      }
      return decodeSvelteFlat(res.data);
    } catch (e) {
      if (i === retries - 1) throw e;
      const delay = RETRY_DELAY * Math.pow(2, i) + randomDelay(0, 500);
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

async function fetchHTML(path, retries = MAX_RETRIES) {
  for (let i = 0; i < retries; i++) {
    try {
      const headers = getHeaders();
      const res = await http.get(path, { headers });
      if (res.status === 403 || res.status === 503) {
        throw new Error(`Blocked (${res.status})`);
      }
      return res.data;
    } catch (e) {
      if (i === retries - 1) throw e;
      const delay = RETRY_DELAY * Math.pow(2, i) + randomDelay(0, 500);
      await new Promise(r => setTimeout(r, delay));
    }
  }
}

function fullUrl(path) {
  if (!path) return null;
  if (path.startsWith("http")) return path;
  return BACKAPI + path;
}

function fmtStreamUrls(streamUrl = []) {
  return (streamUrl || [])
    .filter(s => s?.url && isClean(s.url))
    .map(s => ({ label: s.source, url: s.url }));
}

function fmtDownloads(downloadUrl = []) {
  return (downloadUrl || []).flatMap(fmt =>
    (fmt?.resolutions || []).flatMap(res =>
      (res?.download_links || [])
        .filter(l => l?.url && isClean(l.url))
        .map(l => ({
          format: fmt.format || null,
          quality: res.quality || null,
          host: l.host || null,
          url: l.url,
        }))
    )
  );
}

function fmtSeries(s) {
  if (!s?.slug) return null;
  return {
    id: s.id || null,
    title: s.title || null,
    japaneseTitle: s.japaneseTitle || null,
    slug: s.slug,
    status: s.status || null,
    poster: fullUrl(s.poster),
    score: s.score || null,
    genres: (s.genres || []).map(g => g?.name || g).filter(Boolean),
    studio: s.studio?.name || null,
    season: s.season?.name || null,
    totalEpisodes: s.totalEpisodes || null,
    releaseDate: s.releaseDate || null,
    releaseType: s.releaseType || null,
    url: `${BASE}/series/${s.slug}`,
  };
}

function fmtEpisodeCard(ep) {
  if (!ep) return null;
  return {
    id: ep.id || null,
    seriesTitle: ep.series?.title || null,
    seriesSlug: ep.series?.slug || null,
    episodeNumber: ep.episodeNumber || null,
    subbed: ep.subbed || null,
    poster: fullUrl(ep.series?.poster) || null,
    releasedAt: ep.releasedAt || null,
    streamUrls: fmtStreamUrls(ep.streamUrl),
    downloadUrls: fmtDownloads(ep.downloadUrl),
    url: ep.series?.slug
      ? `${BASE}/series/${ep.series.slug}/episode/${ep.episodeNumber}`
      : null,
  };
}

async function home() {
  const decoded = await fetchDataJson("/", BASE + "/");
  if (!decoded) throw new Error("Gagal decode home __data.json");
  const trending = decoded.trending || {};
  const recently = decoded.recently || {};
  const latestEpisodes = decoded.latestEpisodes || {};
  const html = await fetchHTML("/");
  const $ = cheerio.load(html);
  const banners = [];
  $("[data-embla-slide]").each((_, el) => {
    const img = $(el).find("img[src*='banners']").attr("src") || null;
    const slug = $(el).find("a[href^='/series/']").first().attr("href")?.replace("/series/", "").replace(/\/.*/, "");
    const title = $(el).find("h1 span, h2 span").first().text().trim();
    const desc = $(el).find("p").filter((_, p) => $(p).text().trim().length > 5).first().text().trim();
    if (img && slug && !banners.find(b => b.slug === slug)) {
      banners.push({ image: img, title, slug, description: desc, url: `${BASE}/series/${slug}` });
    }
  });
  return {
    creator: "rynaqrtz",
    page: "home",
    banners,
    trending: (trending.data || []).map(fmtSeries).filter(Boolean),
    recently: (recently.data || []).map(fmtSeries).filter(Boolean),
    latestEpisodes: (latestEpisodes.data || []).map(fmtEpisodeCard).filter(Boolean),
    meta: {
      trending: trending.meta || {},
      recently: recently.meta || {},
      latestEpisodes: latestEpisodes.meta || {},
    },
  };
}

async function seriesList(page = 1, sort_by = "recently", genre = "", limit = 20) {
  const query = new URLSearchParams({ page, sort_by, ...(genre && { genre }) });
  const decoded = await fetchDataJson(`/series?${query}`, BASE + "/");
  let items = (decoded?.allSeries?.data || []).map(s => fmtSeries(s)).filter(Boolean);
  if (!items.length) {
    const html = await fetchHTML(`/series?${query}`);
    const $ = cheerio.load(html);
    $("a[href^='/series/']").each((_, el) => {
      const slug = $(el).attr("href")?.replace("/series/", "").replace(/\/.*/, "");
      const title = $(el).find("img").attr("alt") || "";
      const img = $(el).find("img").attr("src") || null;
      if (slug && title && !items.find(x => x.slug === slug))
        items.push({ slug, title, poster: fullUrl(img), url: `${BASE}/series/${slug}` });
    });
  }
  const total = items.length;
  const start = (page - 1) * limit;
  const end = start + limit;
  const pagedItems = items.slice(start, end);
  return {
    creator: "rynaqrtz",
    page: "series",
    total,
    pagination: {
      currentPage: page,
      lastPage: Math.ceil(total / limit) || 1,
      perPage: limit,
    },
    items: pagedItems,
  };
}

async function detail(slug) {
  const decoded = await fetchDataJson(`/series/${slug}`, BASE + "/");
  if (!decoded) throw new Error(`Gagal decode __data.json untuk: ${slug}`);
  const s = decoded.series || {};
  const eps = decoded.episodes || {};
  const epList = (eps.data || eps || []);
  return {
    creator: "rynaqrtz",
    page: "detail",
    id: s.id || null,
    title: s.title || null,
    japaneseTitle: s.japaneseTitle || null,
    slug,
    description: s.description || null,
    status: s.status || null,
    poster: fullUrl(s.poster),
    score: s.score || null,
    genres: (s.genres || []).map(g => g?.name || g).filter(Boolean),
    studio: s.studio?.name || null,
    season: s.season?.name || null,
    totalEpisodes: s.totalEpisodes || epList.length,
    releaseDate: s.releaseDate || null,
    releaseType: s.releaseType || null,
    batchDownload: s.batchDownloadUrl || null,
    episodesMeta: {
      currentPage: eps.meta?.currentPage || 1,
      lastPage: eps.meta?.lastPage || 1,
      total: eps.meta?.total || epList.length,
    },
    episodes: Array.isArray(epList)
      ? epList
          .map(ep => ({
            episodeNumber: ep.episodeNumber || null,
            title: ep.title || null,
            releasedAt: ep.releasedAt || null,
            url: `${BASE}/series/${slug}/episode/${ep.episodeNumber}`,
          }))
          .filter(ep => ep.episodeNumber)
          .sort((a, b) => +a.episodeNumber - +b.episodeNumber)
      : [],
    url: `${BASE}/series/${slug}`,
  };
}

async function watch(slug, epNumber) {
  const decoded = await fetchDataJson(
    `/series/${slug}/episode/${epNumber}`,
    `${BASE}/series/${slug}`
  );
  if (!decoded) throw new Error(`Gagal decode __data.json untuk: ${slug} ep ${epNumber}`);
  const ep = decoded.episode || {};
  const all = decoded.allEpisodes || decoded.episodes || {};
  const allList = all.data || all || [];
  return {
    page: "watch",
    id: ep.id || null,
    seriesTitle: ep.series?.title || decoded.series?.title || null,
    seriesSlug: ep.series?.slug || slug,
    episodeNumber: ep.episodeNumber || epNumber,
    subbed: ep.subbed || null,
    poster: fullUrl(ep.series?.poster) || fullUrl(decoded.series?.poster) || null,
    releasedAt: ep.releasedAt || null,
    streamUrls: fmtStreamUrls(ep.streamUrl),
    downloadUrls: fmtDownloads(ep.downloadUrl),
    allEpisodes: Array.isArray(allList)
      ? allList
          .map(e => ({
            episodeNumber: e.episodeNumber || null,
            releasedAt: e.releasedAt || null,
            url: `${BASE}/series/${slug}/episode/${e.episodeNumber}`,
          }))
          .filter(e => e.episodeNumber)
          .sort((a, b) => +a.episodeNumber - +b.episodeNumber)
      : [],
    url: `${BASE}/series/${slug}/episode/${epNumber}`,
  };
}

async function episodes(slug, limit = 0) {
  const detailData = await detail(slug);
  const epList = detailData.episodes || [];
  const result = [];
  for (let i = 0; i < epList.length; i++) {
    if (limit > 0 && i >= limit) break;
    const ep = epList[i];
    const epNum = ep.episodeNumber;
    try {
      const watchData = await watch(slug, epNum);
      result.push(watchData);
    } catch (e) {
      result.push({ ...ep, error: e.message });
    }
    await new Promise(r => setTimeout(r, randomDelay(300, 800)));
  }
  return {
    creator: "rynaqrtz",
    page: "episodes",
    seriesTitle: detailData.title,
    slug,
    total: result.length,
    episodes: result,
  };
}

async function search(query, limit = 20) {
  const decoded = await fetchDataJson(`/search?q=${encodeURIComponent(query)}`, BASE + "/");
  let items = (decoded?.allSeries?.data || []).map(s => fmtSeries(s)).filter(Boolean);
  if (!items.length) {
    const html = await fetchHTML(`/search?q=${encodeURIComponent(query)}`);
    const $ = cheerio.load(html);
    $("a[href^='/series/']").each((_, el) => {
      const slug = $(el).attr("href")?.replace("/series/", "").replace(/\/.*/, "");
      const title = $(el).find("img").attr("alt") || "";
      const img = $(el).find("img").attr("src") || null;
      if (slug && title && !items.find(x => x.slug === slug))
        items.push({ slug, title, poster: fullUrl(img), url: `${BASE}/series/${slug}` });
    });
  }
  const filtered = items.filter(item => item.title && item.title.toLowerCase().includes(query.toLowerCase()));
  const total = filtered.length;
  const paged = filtered.slice(0, limit);
  return {
    creator: "rynaqrtz",
    page: "search",
    query,
    total,
    pagination: { currentPage: 1, lastPage: Math.ceil(total / limit), perPage: limit },
    items: paged,
  };
}

const COMMANDS = {
  home: () => home(),
  series: ([p, s, g, l] = []) => {
    const page = parseInt(p) || 1;
    const sort = s || "recently";
    const genre = g || "";
    const limit = parseInt(l) || 20;
    return seriesList(page, sort, genre, limit);
  },
  detail: ([slug]) => {
    if (!slug) throw new Error("Usage: detail <slug>");
    return detail(slug);
  },
  watch: ([slug, ep]) => {
    if (!slug || !ep) throw new Error("Usage: watch <slug> <episode>");
    return watch(slug, ep);
  },
  episodes: ([slug, limit]) => {
    if (!slug) throw new Error("Usage: episodes <slug> [limit]");
    return episodes(slug, parseInt(limit) || 0);
  },
  search: (args) => {
    if (!args.length) throw new Error("Usage: search <query> [limit]");
    let query, limit = 20;
    const last = args[args.length - 1];
    if (/^\d+$/.test(last)) {
      limit = parseInt(last, 10);
      query = args.slice(0, -1).join(" ");
    } else {
      query = args.join(" ");
    }
    return search(query, limit);
  },
};

async function main() {
  const [,, cmd, ...args] = process.argv;
  if (!cmd || !COMMANDS[cmd]) {
    console.error(`Usage: node oploverz.js [${Object.keys(COMMANDS).join("|")}] [...args]`);
    console.error("  node oploverz.js home");
    console.error("  node oploverz.js series [page] [sort] [genre] [limit]");
    console.error("  node oploverz.js detail <slug>");
    console.error("  node oploverz.js watch <slug> <episode>");
    console.error("  node oploverz.js episodes <slug> [limit]");
    console.error("  node oploverz.js search <query> [limit]");
    process.exit(1);
  }
  try {
    const result = await COMMANDS[cmd](args);
    console.log(JSON.stringify(result, null, 2));
  } catch (e) {
    console.error("[error]", e.message);
    if (e.response) console.error(`HTTP ${e.response.status} → ${e.config?.url}`);
    process.exit(1);
  }
}

if (import.meta.url === `file://${process.argv[1]}`) {
  main();
}

export {
  BASE,
  BACKAPI,
  http,
  AD_DOMAINS,
  isClean,
  decodeSvelteFlat,
  fetchDataJson,
  fetchHTML,
  fullUrl,
  fmtStreamUrls,
  fmtDownloads,
  fmtSeries,
  fmtEpisodeCard,
  home,
  seriesList,
  detail,
  watch,
  episodes,
  search,
  COMMANDS,
  main,
};

Rating

1.0(1)

Gimana snippet ini menurutmu?

</> Embed

Embed ke website / blog

<iframe src="https://qrtzcode.vercel.app/api/embed/anime/oploverz" style="width:100%;height:400px;border:none;border-radius:12px;"></iframe>

Related Snippets

otakudesu

seperti biasa bebas kalian modifikasi ubah credit ama creatornya, ak gabakal baper kok😹, semoga bermanfaat ya^^.

66
37

nimegami

Semoga bermanfaat^^.

35
11

neonime

KALIAN BOLEH HAPUS CREDIT, CREATOR MODIFIKASI SESUKA KALIAN.

34
22