[
  {
    "articleStyle": 0,
    "customOrder": -10106439,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "第一会所-小说",
    "sourceUrl": "https://s8cn.com/forum/index.php"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106438,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; SM-G998B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Mobile Safari/537.36 (Yandex)\"\n}\n",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "https://jm-88.cc/3YeBdF\nhttps://jm18c-uoe.cc/\nhttps://jmcomic.me/",
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "禁漫天堂-漫画",
    "sourceUrl": "https://18comic.vip/albums/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106437,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2312DRAABC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "https://asset.brandfetch.io/idIlKj_n7C/idSsbP7h1m.png",
    "sourceName": "pixiv-图片",
    "sourceUrl": "https://www.pixiv.net/novel"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106436,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "zlibrary-杂志图片",
    "sourceUrl": "https://zh.zlir.ru/login?redirectUrl=https%253A%252F%252Fzh.zlir.ru%252F"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106429,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "hanime -动漫",
    "sourceUrl": "https://hanime1.me/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106428,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2312DRAABC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "https://www.missav2.sbs/dm194/cn\nhttps://missav123.to/cn\nhttps://missav123.to/en/genres\nhttps://123av.best/en/series",
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "Miss-av-影视",
    "sourceUrl": "https://missav123.com/cn"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106427,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "jable -影视",
    "sourceUrl": "https://jable.tv/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106425,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "P站-视频",
    "sourceUrl": "https://cn.pornhub.com "
  },
  {
    "articleStyle": 0,
    "customOrder": -10106424,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "每日大赛-视频",
    "sourceUrl": "https://campus.hrdsmyw.com/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106423,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "91吃瓜-视频",
    "sourceUrl": "https://2.miqmrtxcv.cc/category/mrds/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106422,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2312DRAABC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "想干嘛干嘛，新增绘图和视频功能，meimodu翻墙版",
    "sourceGroup": "3小说漫画",
    "sourceIcon": "https://files.catbox.moe/6tgccz.png",
    "sourceName": "Meimodu(墙)🔞",
    "sourceUrl": "https://i.sexyai.ai/IKMum"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106419,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\":\"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36 Reader\"}",
    "injectJs": "if (!/^https:\\/\\/(so\\.toutiao\\.com\\/search\\/?|quark\\.sm\\.cn\\/s|wap\\.sogou\\.com\\/web\\/searchList\\.jsp|m\\.so\\.com\\/s|cn\\.bing\\.com\\/search|www\\.baidu\\.com\\/s)\\?/.test(window.location.href) && !document.getElementById('open-yuedu-bookshelf')) {\n    const btn = document.createElement('div');\n    btn.innerHTML = `<button type=\"button\" id='open-yuedu-bookshelf' style=\"z-index: 9999999999;\n    position: fixed;bottom: 13%;right: 10%;background-color: rgb(255, 153, 0);border-radius: 2px;border: 1px solid rgb(255, 153, 0);color: #fff;\n    font-size:${window.innerWidth/80}vw;font-weight: 400;padding: ${window.innerWidth/400}vw ${window.innerWidth/150}vw;\n    \"onclick=\"window.open('legado://import/addToBookshelf?src=${encodeURIComponent(window.location.href)}','_blank');location.reload();\">加入书架</button>`;\n    document.body.appendChild(btn);\n\n    const btn2 = document.createElement('div');\n    btn2.innerHTML = `<button type=\"button\" id='impotr-booksource' style=\"z-index: 9999999999;\n    position: fixed;bottom: 13%;left: 10%;background-color: rgb(255, 153, 0);border-radius: 2px;border: 1px solid rgb(255, 153, 0);color: #fff;\n    font-size:${window.innerWidth/80}vw;font-weight: 400;padding: ${window.innerWidth/400}vw ${window.innerWidth/150}vw;\n    \"onclick=\"window.open('legado://import/bookSource?src=https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/pixiv.json','_blank');\">导入书源</button>`;\n    document.body.appendChild(btn2);\n}\n\nlet time,num=0;\nconst herfs = new Map();\nfunction onTouchStart(evt) {\n    for (const el of evt.path) {\n        if (el.tagName === \"A\") {\n            if (el.href !== 'javascript:void(0)') {\n                const inner = el.href;\n                herfs.set(el, inner);\n                el.setAttribute('href', 'javascript:void(0)');\n                time = setTimeout(() => {\twindow.open(`legado://import/addToBookshelf?src=${encodeURIComponent(inner)}`, '_blank')\n                }, 600);\n            }\n            break;\n        }\n    }\n}\nfunction onTouchEnd(evt) {\n    if (time) {\n        clearTimeout(time);\n        time = undefined;\n    }\n    for (const el of evt.path) {\n        if (el.tagName === \"A\") {\n            if (el.href === 'javascript:void(0)') {\n                const herf = herfs.get(el);\n                if (herf) {\n                    el.setAttribute('href', herf)\n                }\n            }\n            break;\n        }\n    }\n}\n\nfunction addListener(els){\n    Array.from(els, (item) => {\n        if (item.getAttribute('add-yuedu-bookshelf') !== 'add-yuedu-bookshelf' && item.innerText && item.href && !/^#|^javascript:/.test(item.href)) {\n            item.setAttribute('add-yuedu-bookshelf', 'add-yuedu-bookshelf');\n            item.addEventListener('touchstart', onTouchStart);\n            item.addEventListener('touchend', onTouchEnd);\n            item.addEventListener('touchcancel', onTouchEnd);\n            item.addEventListener('mousedown', onTouchStart);\n            item.addEventListener('mouseup', onTouchEnd);\n        }\n    });\n    num= els.length;\n}\n\nfunction reAdd(){\n    const els = document.getElementsByTagName('a');\n    if(els.length>num)addListener(els);\n}\n\nreAdd();\n\nconst observer = new ResizeObserver(reAdd);\nobserver.observe(document.body);",
    "jsLib": "function sleep(time) {\n    let endTime = new Date().getTime() + time\n    while(true){\n        if (new Date().getTime() > endTime){\n            return;\n        }\n    }\n}\n\nfunction sleepToast(text, second) {\n    let {java} = this\n    java.log(text)\n    java.longToast(text)\n    if (second === undefined) {second = 0.01}\n    sleep(1000*second)\n}\n\nlet bookSourceCommentText = `Pixiv 小说\n\n书源版本：无法获取\n使用说明：📌阅读版本 3.25.0527 及之后版本可用\n可用功能：✅搜索✅发现✅添加网址✅订阅源\n搜索小说：✅单篇✅系列✅标签✅作者\n发现小说：✅关注✅追更✅推荐✅发现\n发现小说：✅收藏✅书签✅首页✅排行\n添加网址：✅Pixiv小说链接✅Pixiv系列链接\n订阅用法：点击订阅源打开小说/系列小说，【刷新】，点击【加入书架】按钮，添加到书架\n\n书源发布：兽人阅读频道 https://t.me/FurryReading\n项目地址：https://github.com/DowneyRem/PixivSource\n使用教程：https://downeyrem.github.io/PixivSource/Pixiv\n\n规则订阅：import 订阅源\nhttps://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/import.json\nhttps://raw.githubusercontent.com/DowneyRem/PixivSource/main/import.json\n\n⚙️ 书源设置：\n设置1️⃣：打开小说 - 菜单 - 登录 - 点击下方按钮\n设置2️⃣：编辑书源 - 基本 - 变量说明 - 修改并保存\n\n🚫 屏蔽作者(本地)：\n设置方法1️⃣：打开小说 - 菜单 - 登录 - 🚫 屏蔽作者\n`.trim()\n\nfunction updateSource() {\n    const {java, source} = this\n    let onlineSource, comment\n    java.longToast(\"🆙 更新书源\\n\\nJsdelivr CDN 更新有延迟\\nGithub 更新需代理\")\n    try {\n        let updateUrl = \"https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/pixiv.json\"\n        onlineSource = JSON.parse(java.get(updateUrl,{'User-Agent': 'Mozilla/5.0 (Linux; Android 14)','X-Requested-With': 'XMLHttpRequest'}).body())[0]  // 第1个书源\n        comment = onlineSource.bookSourceComment.split(\"\\n\")\n    } catch (e) {\n        try {\n            let updateUrl = \"https://raw.githubusercontent.com/DowneyRem/PixivSource/main/pixiv.json\"\n            onlineSource = JSON.parse(java.get(updateUrl,{'User-Agent': 'Mozilla/5.0 (Linux; Android 14)','X-Requested-With': 'XMLHttpRequest'}).body())[0]  // 第1个书源\n            comment = onlineSource.bookSourceComment.split(\"\\n\")\n        } catch (e) {\n            onlineSource = {lastUpdateTime: new Date().getTime(), bookSourceComment: bookSourceCommentText}\n            comment = onlineSource.bookSourceComment.split(\"\\n\")\n        }\n    }\n\n    let htm = `data:text/html; charset=utf-8,\n<html>\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>更新 Pixiv 书源</title>\n    <style> \n    table { text-align: center; margin: 0 auto; } .ann { display: flex; justify-content: center; align-items: center; height: 5vh; } \n    button { background-color: rgb(76, 175, 80); color: white; border: none; border-radius: 4px; height: 6vh; width: 30vw; overflow: hidden; } \n    button span { cursor: pointer; display: inline-block; position: relative; transition: 0.4s; } \n    button span:after { content: '>'; position: absolute; opacity: 0; top: 0; right: 30px; transition: 0.2s; } \n    button:active span { padding-right: 20px; } \n    button:active span:after { opacity: 1; right: -40px; }\n    </style>\n</head>\n\n<body>\n    <table border=\"1\" cellspacing=\"0\">\n        <th colspan=\"2\"> Pixiv 书源 \n        <a href=\"https://downeyrem.github.io/PixivSource/Pixiv\">🔰 使用指南</a>\n        || <a href=\"https://downeyrem.github.io/PixivSource/Sponsor\">❤️ 赞助开发</a>\n        </th>\n        <tr>\n            <td>☁️ 远程版本：${onlineSource.bookSourceComment.split(\"\\n\")[2].replace(\"书源版本：\", \"\")}</td>\n            <td>📆 更新：${java.timeFormat(onlineSource.lastUpdateTime)}</td>\n        </tr>\n        <tr><td colspan=\"2\" style=\"text-align: left;\">${comment.slice(3, 10).join(\"<br>\")}</td></tr>\n        <tr><td colspan=\"2\" style=\"text-align: left;\">${comment.slice(comment.length-15, comment.length).join(\"<br>\")}</td></tr>\n    </table>\n    \n    <table border=\"0\" cellspacing=\"20\">\n        <th colspan=\"2\"> 更新 Pixiv 书源 </th>\n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/pixiv.json\">\n            <button><span>更新书源<br>(Jsdelivr CDN)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/btsrk.json\">\n            <button><span>更新订阅<br>(Jsdelivr CDN)</span></button>\n            </a></div></td>\n        </tr>\n        \n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://raw.githubusercontent.com/DowneyRem/PixivSource/main/pixiv.json\">\n            <button><span>书源链接<br>(GitHub)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://raw.githubusercontent.com/DowneyRem/PixivSource/main/btsrk.json\">\n            <button><span>订阅链接<br>(GitHub)</span></button>\n            </a></div></td>\n        </tr>\n        \n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://codeberg.org/DowneyRem/PixivSource/raw/branch/main/pixiv.json\">\n            <button><span>备用书源链接<br>(Codeberg)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://codeberg.org/DowneyRem/PixivSource/raw/branch/main/btsrk.json\">\n            <button><span>备用订阅链接<br>(Codeberg)</span></button>\n            </a></div></td>\n        </tr>\n    </table>\n</body>\n</html>`\n    java.startBrowser(htm,'更新书源')\n    return []\n}",
    "lastUpdateTime": 1763913600251,
    "loadWithBaseUrl": true,
    "loginUi": "[\n    {\n        \"name\": \"\\uD83C\\uDD7F️ 登录账号\",\n        \"type\": \"button\",\n        \"action\": \"login()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"⚙️ 账号设置\",\n        \"type\": \"button\",\n        \"action\": \"startPixivSettings()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDD19 退出账号\",\n        \"type\": \"button\",\n        \"action\": \"logout()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"🆙 更新书源\",\n        \"type\": \"button\",\n        \"action\": \"updateSource()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDCCC 简要教程\",\n        \"type\": \"button\",\n        \"action\": \"readMe()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {   \"name\": \"\\uD83D\\uDD0D 搜索教程\",\n        \"type\": \"button\",\n        \"action\": \"readMeSearch()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"⭐️ 收藏项目\",\n        \"type\": \"button\",\n        \"action\": \"startGithub()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDD30 使用指南\",\n        \"type\": \"button\",\n        \"action\": \"startGithubReadme()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDC1E 反馈问题\",\n        \"type\": \"button\",\n        \"action\": \"startGithubIssue()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83C\\uDD7F️ 书源频道\",\n        \"type\": \"button\",\n        \"action\": \"startTelegramPixivSource()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDC3A 兽人阅读\",\n        \"type\": \"button\",\n        \"action\": \"startTelegramFurryReading()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"❤\\uFE0F 赞助开发\",\n        \"type\": \"button\",\n        \"action\": \"startGithubSponsor()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    }\n]",
    "loginUrl": "function getWebViewUA() {\n    let userAgent = String(java.getWebViewUA())\n    if (userAgent.includes(\"Windows NT 10.0; Win64; x64\")) {\n        userAgent = \"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36\"\n    }\n    return String(userAgent)\n}\n\nfunction login() {\n    let resp = java.startBrowserAwait(`https://accounts.pixiv.net/login,\n    {\"headers\": {\"User-Agent\": ${getWebViewUA()}}}`, '登录账号', false)\n    if (resp.code() === 200) {\n        getCookie(); getCsrfToken()\n        return true\n    } else {\n        java.log(resp.code()); sleepToast(\"🅿️ 登录账号\\n\\n⚠️ 登录失败\")\n        return false\n    }\n}\n\nfunction logout() {\n    removeCookie()\n    java.startBrowser(\"https://www.pixiv.net/logout.php\", \"退出账号\")\n    removeCookie()\n    sleepToast(`✅ 已退出当前账号\\n\\n退出后请点击右上角的 ✔️ 退出\\n\\n登录请点击【登录账号】进行登录`)\n}\n\nfunction removeCookie() {\n    cookie.removeCookie('https://www.pixiv.net')\n    cookie.removeCookie('https://accounts.pixiv.net')\n    cookie.removeCookie('https://accounts.google.com')\n    cookie.removeCookie('https://api.weibo.com')\n    cache.delete(\"pixivCookie\")\n    cache.delete(\"pixivCsrfToken\")  // 与登录设备有关\n    cache.delete(\"headers\")\n}\n\n// 获取 Csrf Token，以便进行收藏等请求\n// 获取方法来自脚本 Pixiv Previewer\n// https://github.com/Ocrosoft/PixivPreviewer\n// https://greasyfork.org/zh-CN/scripts/30766-pixiv-previewer/code\nfunction getCsrfToken() {\n    let pixivCsrfToken\n    let html = java.webView(null, \"https://www.pixiv.net/\", null)\n    try {\n        pixivCsrfToken = html.match(/token\\\\\":\\\\\"([a-z0-9]{32})/)[1]\n    } catch (e) {\n        pixivCsrfToken = null\n    }\n    // java.log(pixivCsrfToken)\n    cache.put(\"pixivCsrfToken\", pixivCsrfToken)  // 与登录设备有关\n    return pixivCsrfToken\n}\n\nfunction getCookie() {\n    let pixivCookie = String(java.getCookie(\"https://www.pixiv.net/\", null))\n    if (pixivCookie.includes(\"first_visit_datetime\")) {\n        // java.log(pixivCookie)\n        cache.put(\"pixivCookie\", pixivCookie, 60*60)\n        return pixivCookie\n    } else {\n        cache.delete(\"pixivCookie\")\n        // sleepToast(\"未登录账号( pixivCookie)\")\n        return null\n    }\n}\n\nfunction readMe() {\n    sleepToast(`📌 书源使用简要教程\\n\n1️⃣ 导入书源：点击按钮，导入书源\n导入书源后，需要【在书源内登录账号】\n登录后，可在阅读内部搜索小说\n搜索时，需要开启代理/梯子等\\n\n2️⃣ 加入书架：系列目录/小说正文页面\n点击按钮，刷新页面后后可添加至书架\n需要【导入书源】并【在书源内登录账号】\\n\n3️⃣ 搜索小说：阅读内部搜索关键词\n也可添加小说至书架\n　 详细内容：见 🔍 搜索教程\\n\n4️⃣ 详细教程：见 🔰 使用指南`)\n}\n\nfunction readMeSearch() {\n    sleepToast(`🔍 阅读内部搜索说明\\n\n    标签之间需要以【空格】间隔\n    ➖ 排除标签：#标签1 -标签2\n    👤 作者专搜：@作者的名称\n    #️ 标签专搜：#标签1 标签2 \n    ⏬ 字数筛选1：#标签1 标签2 字数3k5\n    ⏬ 字数筛选2：@作者的名称 字数3w5`.replace(\"    \",\"\"), 5)\n}\n\nfunction startBrowser(url, title) {\n    let msg = \"\", headers = `{\"headers\": {\"User-Agent\":\"${getWebViewUA()}\"}}`\n    if (url.includes(\"https://www.pixiv.net\")) {\n        if (url.includes(\"settings\")) msg += \"⚙️ 账号设置\"\n        else msg += \"⤴️ 分享小说\"\n        msg += \"\\n\\n即将打开 Pixiv\\n请确认已开启代理/梯子/VPN等\"\n    } else if (url.includes(\"https://github.com\")) {\n        if (url.includes(\"issues\")) msg += \"🐞 反馈问题\"\n        else if (url.includes(\"doc\")) msg += \"🔰 使用指南\"\n        else msg += \"⭐️ 收藏项目\"\n        msg += \"\\n\\n即将打开 Github\\n请确认已开启代理/梯子/VPN等\"\n    }\n    sleepToast(msg)\n    java.startBrowser(`${url}, ${headers}`, title)\n}\n\nfunction startPixivSettings() {\n    startBrowser(\"https://www.pixiv.net/settings/viewing\", \"账号设置\")\n}\nfunction startGithub() {\n    startBrowser(\"https://github.com/DowneyRem/PixivSource\", \"书源介绍\")\n}\nfunction startGithubIssue() {\n    startBrowser(\"https://github.com/DowneyRem/PixivSource/issues\", \"反馈问题\")\n}\nfunction startGithubReadme() {\n    startBrowser(\"https://downeyrem.github.io/PixivSource/Pixiv\", \"使用指南\")\n}\nfunction startGithubSponsor() {\n    startBrowser(\"https://downeyrem.github.io/PixivSource/Sponsor\", \"赞助开发\")\n}\nfunction startTelegramPixivSource() {\n    startBrowser(\"https://t.me/PixivSource\", \"Pixiv 书源频道\")\n}\nfunction startTelegramFurryReading() {\n    startBrowser(\"https://t.me/FurryReading\", \"兽人阅读频道\")\n}",
    "singleUrl": true,
    "sourceComment": "Pixiv 订阅源\n\n可用功能：✅添加小说（配合书源）✅更新书源\n添加小说：打开小说，【刷新】，点击【加入书架】按钮，添加小说到书架\n\n书源发布：\nPixiv 书源频道 https://t.me/PixivSource\n兽人阅读频道 https://t.me/FurryReading\n\n项目地址：\nhttps://github.com/DowneyRem/PixivSource\nhttps://github.com/eigeen/PixivSourceProject\n\n规则订阅：Import 订阅源\nhttps://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/import.json\nhttps://raw.githubusercontent.com/DowneyRem/PixivSource/main/import.json",
    "sourceGroup": "7备份",
    "sourceIcon": "https://asset.brandfetch.io/idIlKj_n7C/idSsbP7h1m.png",
    "sourceName": "Pixiv",
    "sourceUrl": "https://www.pixiv.net/novel,{\"js\":\"java.longToast('请使用右上角菜单中的【登录】进行登录/退出账号')\"}"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106418,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\"User-Agent\": \"Mozilla/5.0 (Linux; Android 9) Mobile Safari/537.36\",\"referer\": \"{{baseUrl}}\"\n\t}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "遇到广告点击OK 再返回即可 欢迎制作书源\n书源交流群：255399726",
    "sourceGroup": "3小说漫画",
    "sourceIcon": "https://xn--bd1aygdef469chaijkl876anaopq.alicesw13.icu/logo.png",
    "sourceName": "爱丽丝书屋",
    "sourceUrl": "https://xn--bd1aygdef469chaijkl876anaopq.alicesw13.icu/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106417,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "",
    "sourceName": "热辣文",
    "sourceUrl": "https://www.yiyechunxiao.com/"
  },
  {
    "articleStyle": 1,
    "customOrder": -10106414,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "jsLib": "// 本地备用地址\nconst fallbackHosts = [\n  \"https://www.yck.email\",\n  \"https://www.yck2026.top\",\n  \"https://www.yckceo.com\"\n];\n\nconst KEY_WORKING_HOST = \"working_host\";\nconst KEY_HOST_EXPIRE = \"host_expire\";\nconst CACHE_TIME = 300000; // 5分钟缓存\n\nfunction bhost() {\n  const { java, cache } = this;\n  const now = Date.now();\n\n  // 1. 优先直接用缓存（不检测、不提示）\n  const cachedHost = cache.getFromMemory(KEY_WORKING_HOST);\n  const expireTime = cache.getFromMemory(KEY_HOST_EXPIRE) || 0;\n\n  if (cachedHost != null && now < expireTime) {\n    // 直接返回，不检测、不弹窗\n    return cachedHost;\n  }\n\n  // ======================================================\n  // 下面这段 【只有缓存过期/没有缓存时 才会执行】\n  // 平时访问根本不会走到这里！\n  // ======================================================\n  java.toast(\"正在更新最优线路...\");\n\n  const goodList = checkLatency(fallbackHosts, this);\n  let bestHost;\n\n  if (goodList.length > 0) {\n    bestHost = goodList[0].host;\n  } else {\n    bestHost = fallbackHosts[0];\n  }\n\n  // 缓存起来 5 分钟\n  cache.putMemory(KEY_WORKING_HOST, bestHost);\n  cache.putMemory(KEY_HOST_EXPIRE, now + CACHE_TIME);\n\n  java.toast(\"线路已保存，5分钟内不再检测\");\n  return bestHost;\n}\n\n// 检测连通性\nfunction isHostAvailable(host, java) {\n  try {\n    org.jsoup.Jsoup.connect(host)\n      .method(org.jsoup.Connection.Method.HEAD)\n      .timeout(2000)\n      .ignoreHttpErrors(true)\n      .execute();\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\n// 批量测速\nfunction checkLatency(urls, ctx) {\n  const { java } = ctx;\n  const list = [];\n  for (var i = 0; i < urls.length; i++) {\n    let url = urls[i].startsWith(\"http\") ? urls[i] : \"https://\" + urls[i];\n    try {\n      var t1 = Date.now();\n      org.jsoup.Jsoup.connect(url)\n        .method(org.jsoup.Connection.Method.HEAD)\n        .timeout(2000)\n        .ignoreHttpErrors(true)\n        .execute();\n      var t2 = Date.now();\n      list.push({ host: url, latency: t2 - t1 });\n    } catch (e) {}\n  }\n  list.sort(function (a, b) {\n    return a.latency - b.latency;\n  });\n  return list;\n}\n",
    "lastUpdateTime": 1771000555911,
    "loadWithBaseUrl": true,
    "ruleArticles": ".layui-card-body@.ylist",
    "ruleDescription": "<title>{{@h2@a@text}}</title>\n<iframe src=\"legado://import/auto?src={{bhost()}}/yuedu/{{@a@href##.*/yuedu/(.*)/content/id/.*.html##$1}}/json/id/{{@a@href##.*/yuedu/.*/content/id/(.*).html##$1}}.json\" hidden></iframe>\n<br><h3>{{@h2@a@text}}</h3>\n<h5>{{@span.-1@text}}</h5>\n<h6><b>\n↓资源链接，点击复制\n<a href=\"legado://import/auto?src={{bhost()}}/yuedu/{{@a@href##.*/yuedu/(.*)/content/id/.*.html##$1}}/json/id/{{@a@href##.*/yuedu/.*/content/id/(.*).html##$1}}.json\">一键导入</a>\n<textarea id=\"copy\" onclick=\"copy()\">{{bhost()}}/yuedu/{{@a@href##.*/yuedu/(.*)/content/id/.*.html##$1}}/json/id/{{@a@href##.*/yuedu/.*/content/id/(.*).html##$1}}.json</textarea>\n{{@span.-2@text}} {{@p@text}}</b></h6><script>\nfunction copy(){\n\tdocument.getElementById('copy').select()\n\tdocument.execCommand('copy')\n\talert(\"链接复制成功👉请粘贴到对应导入地方导入\")\n}\n</script>",
    "ruleLink": "a@href",
    "ruleNextPage": "page",
    "rulePubDate": "{{@span.-2@text}} {{@.m-right@text}} {{@span.-1@text}}",
    "ruleTitle": "h2@a@text",
    "singleUrl": false,
    "sortUrl": "书源📖::{{bhost()}}/yuedu/shuyuan/index.html?page={{page}}\n书源搜索::{{bhost()}}/yuedu/shuyuan/index.html?keys={{source.getVariable()}}&uid=&order1=time&order2=1&ver=&faxian=&sousuo=&tu=&shengyin=&page={{page}}\n书源合集📖📖::{{bhost()}}/yuedu/shuyuans/index.html?page={{page}}\n订阅源🔔::{{bhost()}}/yuedu/rss/index.html?page={{page}}\n订阅源搜索::{{bhost()}}/yuedu/rss/index.html?keys={{source.getVariable()}}&uid=&order1=time&order2=1&page={{page}}\n订阅源合集🔔🔔::{{bhost()}}/yuedu/rsss/index.html?page={{page}}",
    "sourceGroup": "7备份",
    "sourceIcon": "https://gitee.com/lyc486/yuedu/raw/master/ycktb.gif",
    "sourceName": "源仓库",
    "sourceUrl": "https://www.yckgo.top",
    "style": "a{float:right;text-decoration:none}\nh3,h5{text-align:center}\nh6{margin:0 2;position:sticky;top:30%}\ntextarea{width:100%;border-radius:5px}"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106405,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "injectJs": "if(!self._LOADYEYU){const e={hash(e){let t=String(e),r=2166136261^t.length,n=Math.imul;for(let e=0;e<t.length;e++)r=n(r^t.charCodeAt(e),16777619),r=r<<13|r>>>19;let s=2246822507,a=3266489909,o=e=>(\"00000000\"+(e>>>0).toString(16)).slice(-8);return r^=r>>>16,r=n(r,s),r^=r>>>13,r=n(r,a),r^=r>>>16,o(r)+o(n(2654435769^r,s))+o(n(r^s,a))+o(n(r^a,668265263))}},t=localStorage,r=location,n=\"referral_code\";/register/.test(r.pathname)&&self.referralCode&&(referralCode.disabled=!0);let s=Date.now()>+new Date(\"2026/4/21\")?\"9MJYBNW5\":\"XY5PWBY2\";if(!t[\"user-storage\"]&&!r.search.includes(\"ref\")){let e=new URL(r.href);e.searchParams.append(\"ref\",s),r.href=e}t[n]?.includes(s)||(t[n]=JSON.stringify({code:s,source:\"share_link\",timestamp:Date.now(),expiresIn:0,refFirstTouchHost:r.host})),document.styleSheets[0]?.insertRule(\"header{padding-top:0px !important}\"),document.styleSheets[0]?.insertRule(\"button#register-optional-toggle>div{opacity:0}\"),document.styleSheets[0]?.insertRule(\"#mobile-download-banner,[data-rht-toaster],.z-30 div.bg-gradient-to-r,div:has(>label[for='referralCode']){display:none}\");const a=XMLHttpRequest;XMLHttpRequest=function(){let r,n=new a,{open:o,send:i}=n;return n.open=(...e)=>{r=e[1],o.apply(n,e)},n.send=async a=>{if(a&&/sign-up\\/email$|quick-register$/.test(r))try{let r=JSON.parse(a),n=t.yeyu_code;n&&/^[0-9A-Z]{8}$/.test(n)&&(s=n),a=JSON.stringify({...r,referralCode:s,fingerprint:e.hash([r.fingerprint||Math.random(),Date.now()/432e5|0].join(\"\"))})}catch{}i.call(n,a)},n},self._LOADYEYU=!0}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": false,
    "ruleArticles": "@js:\n[{\nhref:baseUrl,\ntitle:'夜语AI',\ntime:new Date().toLocaleString(),\nimg:\"https://yeyu.ai/install-emtry.webp\"\n}];",
    "ruleImage": "img",
    "ruleLink": "href",
    "rulePubDate": "time",
    "ruleTitle": "title",
    "singleUrl": false,
    "sortUrl": "首页::/explore/app/?ranking=overall_rank\n抽卡::/explore/random/\n签到::/user/points/\n历史收藏::/user/history/?tab=favorites\n登录注册::/user/register/",
    "sourceComment": "无限制ai对话、自定义小说创作，每日签到、任务可免费领积分",
    "sourceGroup": "3小说漫画",
    "sourceIcon": "https://yeyu.ai/install-emtry.webp",
    "sourceName": "🔞夜语AI",
    "sourceUrl": "https://yeyu.ai/r/KKPVLG8F"
  },
  {
    "articleStyle": 0,
    "customOrder": -10106404,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "injectJs": "let c=location,d=localStorage,e=document;\nif(/\\u98ce\\u6708/.test(e.title)){if(!d.console_token&&!/ref_id/.test(c.href)){let f=d.ref_id=atob('OGExYTAzNGMtZmI2MC00Y2I4LTk3MDktNTZiZjRmNWE1MWQy'),a=new URL(c.href);a.searchParams.set('ref_id',f);c.href=a}e.styleSheets[0]?.insertRule('form\\x3e.mt-1.mb-4.text-xs{display:none}')};\n\nlet aifycheck={checkUrl(a){return new Promise((c,b)=>{let d=Date.now();setTimeout(c,4E3,4E3);a.endsWith(\"\\x3d\")&&(a+=d);fetch(a,{mode:\"no-cors\",method:\"HEAD\"}).catch(()=>c(6E3)).then(()=>c(Date.now()-d))})},checkUrls(a){return Promise.allSettled(a.map(this.checkUrl)).then(c=>c.map(b=>b.value||b.reason))},getTimeStr(a){return a===6E3?\"\\ud83d\\udeab\\u88ab\\u5899/\\u5931\\u6548/\\u6545\\u969c\":a<1E3?`\\ud83d\\udfe2\\u5ef6\\u65f6: ${a} ms`:a<1200?`\\ud83d\\udd35\\u5ef6\\u65f6: ${a} ms`:a<1500?`\\ud83d\\udfe3\\u5ef6\\u65f6: ${a} ms `:\na<2E3?`\\ud83d\\udfe0\\u5ef6\\u65f6: ${a} ms `:a===4E3?\"\\u26ab\\u5ef6\\u65f6 \\x3e 4 s\":`\\ud83d\\udd34\\u5ef6\\u65f6: ${a} ms `},checkUrlList(){let a=document.querySelectorAll(\"#all-site-list a\"),c=document.querySelector(\"#byym\");a.length===0?self.onload=()=>{this.checkUrlList();let b=document.createElement(\"style\");b.textContent=\"#all-site-list a\\x3e*{text-align:center}\";document.head.appendChild(b)}:c.text=\"\\u68c0\\u6d4b\\u7f51\\u5740\\u4e2d...\";a.forEach(async b=>{b._textContent||(b._textContent=b.textContent);\nlet d=this.getTimeStr(await this.checkUrl(b.href=b.href.replace(\"p:\",\"ps:\")));b.innerHTML=`<p><b>${(new URL(b.href)).host}</b></p><p>${b._textContent}</p><p>${d}</p>`});c?.scrollIntoView();c?.firstElementChild?.textContent.includes(\"\\u5907\\u7528\\u57df\\u540d\")&&(c.firstElementChild.innerHTML=`\\u5907\\u7528\\u57df\\u540d (${(new Date).toLocaleTimeString()})<p>\\u53cc\\u51fb\\u7f51\\u9875\\u53ef\\u5237\\u65b0\\u68c0\\u6d4b</p>`)}};\n/aify.pages.dev|aifordum.github.io/.test(location.host)&&(aifycheck.checkUrlList(),self.addEventListener(\"dblclick\",()=>aifycheck.checkUrlList()));",
    "jsLib": "datas = [[{host:\"awsprod.aiero.cc\"},{host:\"aiaha.xyz\"},{host:\"acquant.xyz\"},{host:\"acquainte.xyz\"},{host:\"beling.xyz\"},{host:\"ai-xan.xyz\"},{host:\"aiwhatis.xyz\"},{host:\"aquantancee.xyz\"},{host:\"aquante.xyz\"},{host:\"aitrader.wiki\"},{host:\"aisearches.xyz\"},{host:\"aigirlfriendnetwork.com\"},{host:\"aigirlfriendnow.com\"}],[{host:\"aifun.ltd\",url:\"https://aifun.ltd/fcWoo\",img:1},{host:\"aifordum.github.io\",url:`https://aifordum.github.io?ref_id=8a1a034c-fb60-4cb8-9709-56bf4f5a51d2&t=`,img:1},{host:\"aify.pages.dev\",img:1}]];\nid = \"8a1a034c-fb60-4cb8-9709-56bf4f5a51d2\";\ndatas.forEach(list => {\n    list.forEach((x, i) => {\n        if (!x.url) x.url = `https://${x.host}?ref_id=${id}`;\n        if (!x.title) x.title = `${i+1}【${x.host}】`;\n    });\n});\n\nfunction getTimeList(urls) {\n    return this.java.webView(`<script>function checkUrl(url){return new Promise((res,rej)=>{let t=Date.now(),id=setTimeout(rej,3e3,4e3);if(url.endsWith('='))url+=t;fetch(url,{mode:'no-cors',method:'HEAD'}).catch(()=>rej(5e3)).then(()=>res(Date.now()-t)&&clearTimeout(id))})}function checkUrls(arr){return Promise.allSettled(arr.map(checkUrl)).then(a=>a.map(x=>x.value||x.reason))}checkUrls(${JSON.stringify(urls)}).then(arr=>result=JSON.stringify(arr));</script>`, \"about:blank\", \"self.result\");\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "loginUrl": "/fcWoo",
    "ruleArticles": "@js:\nlet list = datas[java.hexDecodeToString(src)];\nlet arr = JSON.parse(getTimeList(list.map(x => x.url)));\nresult = list.map((obj, i) => {\n  const x = arr[i];\n  obj.img = source.sourceIcon;\n  obj.time = x === 5000 ? '🚫被墙/失效/故障' :\n    x < 1000 ? `🟢延时：${x} ms` :\n    x < 1200 ? `🔵延时：${x} ms` :\n    x < 1500 ? `🟣延时：${x} ms ` :\n    x < 2000 ? `🟠延时：${x} ms ` :\n    x === 4000 ? '⚫延时 > 3 s' :\n    `🔴延时：${x} ms `;\n  return obj;\n});\n",
    "ruleImage": "img",
    "ruleLink": "url",
    "rulePubDate": "time",
    "ruleTitle": "title",
    "singleUrl": false,
    "sortUrl": "路线列表::data:;base64,MA==,{\"type\":0}\n发布页::data:;base64,MQ==,{\"type\":0}",
    "sourceComment": "gemini/claude/grok/GPT/deepseek\n/kimi/glm/doubao\n右上角清除后可刷新",
    "sourceGroup": "3小说漫画",
    "sourceIcon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNjAiIGhlaWdodD0iMzYwIiB2aWV3Qm94PSIwIDAgMzYwIDM2MCIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTI5Mi44NiA5Ni4yNDc2QzI5NC4zNDUgOTYuMjQ3NiAyOTYuMzcgOTYuNzg3MyAzMDUuNDE1IDEwMS42NDdDMzE0Ljg2NSAxMDYuNzc3IDMxNi40ODUgMTA4LjkzOCAzMTYuNDg1IDExMS4yMzNDMzE2LjQ4NSAxMTMuMjU4IDMxNC45OTkgMTE1LjI4MyAzMDguMzg1IDExOS40NjdMMzAzLjc5NCAyNDkuNzQzQzMwMy41MjQgMjU3LjE2OCAzMDIuNzE1IDI2Mi4yOTggMzAxLjA5NSAyNjUuNDAzQzI5OS40NzUgMjY4Ljc3OCAyOTUuNDI1IDI3Mi4wMTcgMjg4LjQwNSAyNzUuNzk3QzI3OS42MyAyODAuNTIyIDI3Ni45MyAyODEuMTk4IDI3NS40NDUgMjgxLjE5OEMyNzIuNDc1IDI4MS4xOTggMjcwLjQ1IDI3OS40NDIgMjY5LjkxIDI3Ni4zMzdDMjY5LjEgMjcyLjE1MiAyNjcuNDggMjY5LjA0NyAyNjUuMTg1IDI2Ni44ODdDMjYzLjQzIDI2NS4yNjcgMjU5LjI0NSAyNjIuNTY3IDI0OC4zMSAyNTcuOTc3TDI0Ni40MTkgMjU3LjE2OEwyNDcuOTA1IDI0Ny44NTJMMjUwLjc0IDI0OC4zOTJDMjY1Ljk5NSAyNTEuNjMyIDI3MS44IDI1Mi4xNzIgMjc0LjA5NSAyNTIuMTcyQzI3OC41MDIgMjUyLjAzOSAyNzkuNjA2IDI1MS41MDkgMjc5LjYyOSAyNTEuNDk4QzI3OS42MjkgMjUxLjQ5OCAyNzkuOSAyNTAuOTU4IDI4MC4wMzUgMjQ5Ljc0M0wyODIuNzM1IDE3MS4wMzhMMjQ1Ljg3OSAxNzMuNjAyTDI0Ni4yODUgMTUyLjI3MkwyODMuNTQ0IDE0OS40MzdMMjg0LjYyNSAxMTkuMTk4TDIzMS40MzUgMTI0LjA1N0MyMzEuMDMgMTM5Ljg1MiAyMjkuMTQgMTgxLjQzMyAyMjguMTk1IDE5NS4yMDNMMjY4LjU2IDE5Mi43NzJMMjY3Ljg4NSAyMDQuNTE3TDIyNi44NDUgMjA2LjgxMkMyMjQuODIgMjI0LjYzMiAyMTkuOTYgMjM5LjM0NyAyMTIuNCAyNTAuNTUyQzIwNC43MDUgMjYyLjAyNyAxOTIuMDE0IDI3My4wOTcgMTc1LjAwNCAyODMuNjI3TDE3My4xMTUgMjg0Ljg0MkwxNjcuMzEgMjc4LjYzMkwxNjcuMTc1IDI3OC40OThMMTY5LjIgMjc2LjYwOEMxNzkuNzMgMjY2Ljg4OCAxODcuNjk0IDI1Ny40MzggMTkyLjk1OSAyNDguNjYzQzE5OC4yMjQgMjM5Ljg4OCAyMDEuODcgMjI5Ljc2MiAyMDMuODk1IDIxOC41NTdDMjA1LjkyIDIwNy4yMTcgMjA3LjI3IDE5MC43NDcgMjA3LjgxIDE2OS44MjNDMjA4LjM1IDE0OC42MjggMjA4LjYyIDEyNy43MDIgMjA4LjYyIDEwNy4wNDdWMTAzLjQwM0wyMTIuMTI5IDEwNC40ODNDMjE4LjQ3NCAxMDYuNTA4IDIyNC45NTQgMTA5LjA3MiAyMzEuMjk5IDExMi4xNzdMMjg0LjM1NSAxMDcuMTgyTDI4OC4yNyA5OS42MjI2QzI4OS43NTUgOTcuMDU3NiAyOTEuNTEgOTYuMjQ3NiAyOTIuODYgOTYuMjQ3NlpNMTM4LjQxOSA3NC4xMDc5QzEzOS45MDQgNzQuMTA3OSAxNDEuNTI1IDc0LjY0NzkgMTQ5LjIyIDc5Ljc3NzlDMTU2LjkxNSA4NC45MDc2IDE1OC40IDg3LjMzNzYgMTU4LjQgODkuNDk3NkMxNTguNCA5Mi40Njc2IDE1NS41NjQgOTQuODk3NCAxNDkuMDg0IDk3LjQ2MjRDMTQ3Ljg2OSAxMTMuNjYyIDE0Ny4xOTQgMTI5LjMyMyAxNDYuOTI0IDE0NC4wMzhDMTQ2LjY1NCAxNTkuMDIzIDE0Ny4zMjkgMTcyLjI1MyAxNDkuMDg0IDE4My4xODhDMTUwLjcwNCAxOTMuOTg4IDE1Mi44NjUgMjAxLjU0OCAxNTUuNDMgMjA2LjAwMkMxNTYuOTE1IDIwOC41NjcgMTU3Ljg2IDIwOS45MTggMTU4LjUzNSAyMTAuNzI4QzE1OS4yMSAyMDkuMTA4IDE2MC4yOSAyMDYuMTM4IDE2MS45MSAyMDEuODE4QzE2NC4wNyAxOTUuODc4IDE2Ni4zNjUgMTg4LjU4OCAxNjkuMDY1IDE3OS44MTNMMTY5Ljg3NSAxNzcuMTEzTDE3Ny4wMyAxNzkuNTQzTDE3Ni42MjUgMTgxLjgzN0MxNzMuNzkgMTk5LjY1NyAxNzIuMzA0IDIxMS4xMzMgMTcyLjE2OSAyMTUuOTkzQzE3Mi4xNjkgMjIwLjcxOCAxNzIuNDQgMjI1LjE3MyAxNzMuMjUgMjI5LjQ5M0MxNzQuNDY0IDIzNS43MDMgMTc0LjYgMjM3LjE4OCAxNzQuNiAyMzcuOTk4QzE3NC42IDI0MS42NDMgMTcyLjE3IDI0My45MzggMTY4LjUyNSAyNDMuOTM4QzE2Ni42MzUgMjQzLjkzOCAxNjMuMjU5IDI0My4yNjMgMTU0Ljc1NCAyMzcuOTk4QzE0OC40MSAyMzMuOTQ4IDE0My4xNDUgMjI3Ljg3MiAxMzkuMDk1IDIxOS42MzdDMTM1LjE4IDIxMS42NzIgMTMyLjM0NCAyMDAuODczIDEzMC41ODkgMTg3LjY0M0MxMjguODM0IDE3NC41NDggMTI4LjE2IDE1OS44MzMgMTI4LjQzIDE0My43NjhDMTI4LjcgMTI4LjY0OCAxMjkuMjM5IDExMy4xMjMgMTMwLjA0OSA5Ny4xOTI5TDY3LjgxNDkgMTAyLjg2M0M2Ny4wMDQ5IDEzOS40NDcgNjUuNzkwMiAxNjQuNDIyIDY0LjMwNTIgMTc3LjM4MkM2Mi44MjAyIDE5MC43NDcgNTkuMTc0OSAyMDMuMTY4IDUzLjc3NDkgMjE0LjM3M0M0OC4zNzQ5IDIyNS40NDMgMzkuMzI5OCAyMzcuMTg4IDI2Ljc3NDkgMjQ5LjMzN0wyNC40OCAyNTEuNjMyTDE5LjM1MDEgMjQ0LjIwOEwxOS40ODQ5IDI0NC4wNzNMMjAuNjk5NyAyNDIuNDUzQzI5Ljg3OTcgMjMwLjQzOCAzNi43NjQ3IDIxNy4wNzIgNDAuOTQ5NyAyMDIuNzYyQzQ1LjI2OTYgMTg4LjMxNyA0Ny43MDAyIDE2Ny43OTcgNDcuOTcwMiAxNDEuODc3QzQ4LjI0MDIgMTI1Ljk0OCA0Ny45Njk5IDEwNy40NTMgNDcuMDI0OSA4Ny4wNjc5VjgzLjU1ODFMNTAuMjY1MSA4NC4zNjc3QzU2LjYwOTkgODUuNzE3NyA2Mi42ODQ3IDg4LjAxMjggNjguNjI0NSA5MS4xMTc3TDEyOS42NDUgODUuNDQ3OEwxMzQuMjM1IDc3LjQ4MjlDMTM1LjMxNSA3NS40NTgxIDEzNi44IDc0LjI0MzEgMTM4LjQxOSA3NC4xMDc5Wk0xMDkuOTM1IDEyNS42NzdDMTEwLjYxIDEyOS4zMjIgMTEyLjM2NSAxMzguOTA4IDExMy4zMSAxNTAuMjQ4QzExNy4wOSAxNTEuNDYzIDEyMC44NyAxNTMuMzUzIDEyNC42NSAxNTUuOTE4TDEyNi44MSAxNTcuMjY3TDExNy40OTUgMTczLjQ2N0MxMTcuNDcgMTczLjQ1MSAxMTMuOTgzIDE3MS4xNzEgMTEzLjQ0NSAxNzAuOTAyQzExMi41IDE4My4xODcgMTA5LjM5NSAxOTIuMjMyIDEwNC40IDE5Ny45MDJDMTAwLjYyIDIwMi4wODcgOTUuNzU5OCAyMDQuMzgyIDkwLjM1OTkgMjA0LjUxN0g4OS40MTQ2TDg5LjE0NSAyMDQuMzgyQzg2Ljk4NTEgMjA0LjM4MiA4NC42OSAyMDQuMTEyIDgyLjM5NSAyMDMuNDM3Qzc0LjU2NTEgMjAxLjI3NyA2OS41Njk5IDE5NC45MzMgNjguNDg5NyAxODYuMTU4QzY3LjEzOTggMTc1LjA4OCA3Mi44MDk2IDE2Mi4yNjIgODIuMTI0NSAxNTQuOTcyQzg2LjE3NDQgMTUxLjczMiA5MC43NjQ2IDE0OS43MDcgOTUuNjI0NSAxNDguNzYyQzk1LjA4NDUgMTQyLjU1MiA5NC4xNCAxMzYuMjA3IDkzLjA2MDEgMTMwLjY3Mkw5Mi42NTQ4IDEyOC4zNzdMMTA5LjI2IDEyMi43MDhMMTA5LjkzNSAxMjUuNjc3Wk05Ni4xNjQ2IDE2Ny4yNTdDOTQuNDA5NyAxNjcuNzk3IDkyLjkyNDggMTY4LjYwNyA5MS40Mzk5IDE2OS42ODdDODYuNDQ0OSAxNzMuNjAyIDg0LjY5MDIgMTc5LjgxMiA4NS4wOTUyIDE4Mi45MThDODUuMzY1MiAxODQuODA3IDg1LjkwNDcgMTg1LjIxMyA4Ny4xMTk2IDE4NS42MThDODguMDY0NiAxODUuODg4IDg5LjAwOTggMTg2LjAyMiA4OS44MTk4IDE4Ni4wMjJDOTEuMzA0NCAxODYuMDIyIDkxLjg0NDYgMTg1LjQ4MyA5Mi4yNDk1IDE4NS4wNzhDOTMuNTk5NSAxODMuNDU4IDk1Ljg5NTMgMTc5LjEzNyA5Ni4zMDAzIDE2Ny4yNTdIOTYuMTY0NlpNMTg5LjQ1IDE2My44ODJMMTcwLjgyIDE2NC44MjhMMTcyLjAzNSAxMTEuMDk3TDE5MC44IDEwOS42MTNMMTg5LjQ1IDE2My44ODJaTTM0MC4xMSAxNDIuMTQ4TDMyMy43NzUgMTQzLjIyOEwzMjQuNDUgMTI2Ljc1N0wzNDAuNjUgMTI1LjU0M0wzNDAuMTEgMTQyLjE0OFpNMjc1LjkwMSAxNS4yMzU5QzI4MC45NzcgMTQuNTg3OSAyODUuMDggMTguMDQzNiAyODUuMDgxIDIyLjc5NTRMMjg0LjIxNyA3NC40MTk1QzI4NC4xMDkgNzkuMTcxNSAyNzkuODk3IDgzLjI3NTUgMjc0LjgyMSA4My43MDc1TDIwMC44NDEgODkuNTM5NkwxODcuNzczIDk3Ljc0NzZMMTg2LjgwMSA5MC42MTk3QzE4Mi4xNTcgOTEuMDUxNiAxNzguNDg1IDg3LjcwMzggMTc4LjQ4NSA4My4yNzU5VjM0LjY3NTNDMTc4LjQ4NSAzMC4xMzk1IDE4Mi4yNjUgMjYuMDM1NyAxODYuOTA5IDI1LjQ5NTZMMjc1Ljc5MiAxNS4yMzU5SDI3NS45MDFaTTIxOS43NDEgMzEuNTQzNUwyMDEuODEzIDc5LjA2NEwyMDcuMTA1IDc4Ljg0NzJMMjEyLjYxMyA2NC4yNjgxTDIyNi41NDQgNjMuNTExM0wyMzIuMDUzIDc3Ljg3NTVWNzcuNzY4MUwyNDAuNjkzIDc3LjQ0MzlMMjIyLjc2NSAzMS4yMTkzTDIxOS43NDEgMzEuNTQzNVpNMjQxLjg4MSAyOS4zODMzTDI0MS41NTcgNjQuOTE1NkgyNTMuMjIxTDI1My41NDQgMjguMzAzMkwyNDEuODgxIDI5LjM4MzNaTTIyNC42MDEgNTguNzU5M0wyMTQuNTU3IDU5LjI5OTNMMjE5LjYzMyA0NS45MDc3TDIyNC42MDEgNTguNzU5M1oiIGZpbGw9ImJsYWNrIi8+PC9zdmc+",
    "sourceName": "AI风月\n💞",
    "sourceUrl": "https://aifun.ltd"
  },
  {
    "articleStyle": 1,
    "customOrder": -10102258,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "ul@li",
    "ruleContent": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<title>内容提取</title>\n<!-- v2025.05.10 -->\n\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.css\" />\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.js\"></script>\n<style>\n    body { font-family: Arial, sans-serif; font-size: 16px; }\n    #title, #page, #loading-status { margin: 0 auto; font-size: 20px; text-align: center; }\n    #description, #urls, #video-url, #video-sources, #messages { width: 100%; max-width: 800px; margin: 1.5px auto; font-size: 14px; text-align: left; word-wrap: break-word; white-space: pre-wrap; }\n    #text, #text :not(img), #text img + * { text-indent: 2em; width: 100%; font-size: 16px; line-height: 1.5em; margin-top: 0; margin-bottom: 0; word-wrap: break-word; white-space: pre-wrap; }\n    img, #text img { width: 100%; height: auto; display: block; margin-bottom: 1.5px; }\n    .flex-container { display: flex; justify-content: center; align-items: center; gap: 10px; margin: 1.5px 0; font-size: 14px; }\n    button, select { flex: 1 1 31%; padding: 3px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; cursor: pointer; background-color: #f9f9f9; transition: background-color 0.3s ease; margin: 1.5px; min-width: 0; font-size: 14px; }\n    #url-select, #video-source-select { flex: 1 1 100%; margin-left: 0; margin-right: 0; text-align: center; }\n    #video-element { width: 100%; height: auto; }\n    textarea { width: 100%; height: auto; min-height: 100px; box-sizing: border-box; resize: vertical; }\n    .error, .warn { color: red; }\n</style>\n</head>\n<body>\n    <h3 id=\"title\">{{@@title@text||h1.0@text||h2.0@text||.title.0@text}}</h3>\n    <p id=\"description\">{{@@.info.0@html||.jianjie@html}}</p>\n    <p id=\"page\" style=\"display:none;\">共<span id=\"total-pages\">1</span>页</p>\n    <p id=\"loading-status\" style=\"display:none;\"></p>\n\n    <div class=\"flex-container\" id=\"loading-buttons\" style=\"display:none;\">\n        <button id=\"prev-page-btn\">上一页</button>\n        <button id=\"next-page-btn\">下一页</button>\n        <button id=\"auto-load-btn\">自&nbsp;&nbsp;动</button>\n    </div>\n    \n    <div class=\"flex-container\">\n        <select id=\"url-select\" style=\"display:none;\"></select>\n    </div>\n    \n    <div class=\"flex-container\">\n        <button id=\"toggle-urls-btn\">显/隐网址</button>\n        <button id=\"toggle-messages-btn\">显/隐信息</button>\n        <button id=\"toggle-debug-btn\">显/隐调试</button>\n    </div>\n    <div id=\"urls\"></div>\n    <div id=\"messages\"></div>\n    <div id=\"debug-info\"></div>\n    <div id=\"video-url\"></div>\n    <div id=\"video-container\" style=\"display: none;\">\n        <video id=\"video-element\" controls preload=\"auto\" width=\"640\" height=\"264\">\n            <source id=\"video-source\" src=\"\" type=\"\">您的浏览器不支持 video 标签。\n        </video>\n    </div>\n    <div class=\"flex-container\" id=\"video-source-container\" style=\"display: none;\">\n        <select id=\"video-source-select\" onchange=\"updateVideoSource()\"></select>\n    </div>\n    <div id=\"images\"></div>\n    <div id=\"text\"></div>\n\n    <script>\n        // 配置对象，包含各种选择器、延迟时间等配置项\n        const config = {    \n            videoSelector: 'body', // 视频选择器\n            imgSelector: '.gridlane-box-inside img,.photos figure img,.content p img', // 图片选择器\n            textSelector: '#content', // 文本选择器\n            debugSelector: '#content, .page, .pager, .content, script', // 调试信息选择器\n            swapImageAttributes: false, // 是否交换图片属性\n            delayTime: 1500, // 延迟提取时间\n            retryDelayTime: 1500, // 重试加载延迟时间\n            maxLoadAttempts: 3, // 最大加载次数\n            autoLoading: false, // true自动模式，false单页模式\n            debugOnce: 0, // 只在特定索引输出一次调试信息\n            totalPagesText: '{{@@.page.0@a.-2@textNodes}}', // 总页码\n            urlSuffixToRemove: /\\.html$/, // 移除url后缀\n            pageUrlText: '{urlPrefix}_{i}.html', // 拼接URL模板        \n            ListMode: true, // true网址列表模式，false网址拼接模式    \n            initialUrls: `{{@@#sort-item-5.0@a@href}}`, // 网址\n            initialUrlsName: `{{@@#sort-item-5.0@a@span@text}}`, // 网址名称\n            sourceurl: '', // 来源URL前缀\n        };\n\n        let videoSources = []; // 存储视频源数组\n        let loadAttempts = {}; // 记录每个URL的加载尝试次数\n        let urls = []; // 存储所有页面的URL\n        let imageBox;\n        let textBox;\n        let currentPageIndex = 0; // 当前页面索引\n        let canLoadNextPage = true; // 控制是否可以加载下一页\n        let autoLoadInProgress = false; // 自动加载状态\n\n        // 构建URL列表\n        function buildUrls(totalPages, baseUrl) {\n            let initialUrlsArray = config.initialUrls.trim().split('\\n').filter(url => url.trim() !== '');\n            let initialUrlsNameArray = config.initialUrlsName.trim().split('\\n').filter(name => name.trim() !== '');\n\n            if (config.ListMode && initialUrlsArray.length > 0) {\n                if (initialUrlsArray.length !== initialUrlsNameArray.length) {\n                    $('#messages').append(`<span class=\"warn\">警告：initialUrls 和 initialUrlsName 的长度不匹配。</span><br>`);\n                }\n\n                urls = initialUrlsArray.map(url => {\n                    if (config.sourceurl && url.startsWith('/') && !/^https?:\\/\\//i.test(url)) {\n                        return config.sourceurl.replace(/\\/$/, '') + url;\n                    } else {\n                        return url;\n                    }\n                });\n\n                urls.forEach((url, index) => {\n                    const name = initialUrlsNameArray[index] || `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            } else {\n                if (totalPages === 1) {\n                    urls.push(baseUrl);\n                } else {\n                    urls.push(baseUrl);\n                    for (let i = 2; i <= totalPages; i++) {\n                        urls.push(config.pageUrlText.replace('{urlPrefix}', baseUrl.replace(config.urlSuffixToRemove, '').replace(/\\/$/, '')).replace('{i}', i));\n                    }\n                }\n\n                urls.forEach((url, index) => {\n                    const name = `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            }\n\n            $('#total-pages').text(urls.length);\n            toggleNavigationButtons();\n            toggleTotalPagesDisplay();\n        }\n\n        // 规范化URL\n        function normalizeUrl(url) {\n            if (typeof url !== 'string' || !url.trim()) {\n                return '';\n            }\n            const match = url.match(/['\"](.*?)['\"]/);\n            if (match && match[1]) {\n                url = match[1];\n            }\n\n            function processUrl(str) {\n                str = str.trim();\n                str = str.replace(/\\\\u[\\dA-F]{4}/gi, match => String.fromCharCode(parseInt(match.replace(/\\\\u/g, ''), 16)));\n                str = decodeURIComponent(str);\n                str = str.replace(/^http:\\/([^/])/, 'http://$1');\n                str = str.replace(/^https:\\/([^/])/, 'https://$1');\n                return str;\n            }\n            return processUrl(url);\n        }\n\n        // 清空容器内容\n        function clearContainers() {\n            $('#messages').empty();\n            $('#images').empty();\n            $('#text').empty();\n        }\n\n        // 更新图像源\n        function updateImageSrc(elements, shouldSwap) {\n            elements.each(function () {\n                const $this = $(this);\n                const attrsToUpdate = {};\n                if (shouldSwap) {\n                    ['data-original', 'data-src', 'data-url'].forEach(attr => {\n                        if ($this.attr(attr)) {\n                            attrsToUpdate['src'] = $this.attr(attr);\n                        }\n                    });\n                }\n                $this.attr(attrsToUpdate);\n            });\n            return elements;\n        }\n\n        // 切换导航按钮显示状态\n        function toggleNavigationButtons() {\n            if ($('#url-select option').length > 1 && !config.autoLoading) {\n                $('#loading-buttons').show();\n                $('#url-select').show();\n            } else {\n                $('#loading-buttons').hide();\n                $('#url-select').hide();\n            }\n        }\n\n        // 显示加载状态\n        function showLoadingStatus(pageNumber) {\n            const selectedOption = $('#url-select option:selected').text();\n            $('#loading-status').text(`正在加载：${selectedOption}`).show();\n        }\n\n        // 隐藏加载状态\n        function hideLoadingStatus() {\n            $('#loading-status').hide();\n        }\n\n        // 加载指定索引的内容\n        function loadContent(index) {\n            if (index < 0 || index >= urls.length || !canLoadNextPage) return;\n            canLoadNextPage = false;\n            currentPageIndex = index;\n            $('#url-select').val(index);\n            $('#messages').append(`<div>当前地址: <span class=\"warn\">${urls[index]}</span></div>`);\n            if (autoLoadInProgress) {\n                showLoadingStatus(index + 1);\n            }\n            $.ajax({\n                url: urls[index],\n                type: 'GET',\n                success: function (data) {\n                    try {\n                    const $data = $(data);\n                    let updatedHtmlContent = data.replace(/(['\"])(\\/\\/)(?!\\/)/g, '$1https://')\n                        .replace(/src=\"upload/gi, 'src=\"/upload')\n                        .replace(/style=[\"'][^'\"]+[\"']/gi, '')\n                        .replace(/\\\\\\//g, '/');\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(updatedHtmlContent, \"text/html\");\n\n                    if (config.debugOnce === index) {\n                        const debugElements = $(doc).find(config.debugSelector);\n                        if (debugElements.length > 0) {\n                            const debugContents = $('<pre>').html(debugElements.clone().wrapAll('<div/>').parent().html()).html();\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">${debugContents}</textarea></span>`);\n                        } else {\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">调试信息未提取到内容，请检查选择器！</textarea></span>`);\n                        }\n                    }\n                    // 方法1：提取视频\n                    const videoSources1 = [];\n                    const videoContents = $(doc).find(config.videoSelector);\n                    const videoTags = $(videoContents).find('video, source');\n                    videoTags.each(function() {\n                        const videosrc = $(this).attr('src') || \n                                     $(this).attr('data-src') || \n                                     $(this).attr('data-original') || '';\n                        \n                        if (videosrc) {\n                            videoSources1.push(videosrc);\n                        }\n                    });\n                    //反馈\n                    if (videoSources1.length > 0) {\n                        $('#messages').append(`<span>方法1，找到 ${videoSources1.length} 个视频。</span><br>`);\n                    }\n\n                    // 方法2：正则提取视频\n                    const regex = /['\"]https?[^'<>\"]+(m3u8|mp4|webm|ogg|flv|mp3|m4a|wav|ape|flac)([^'<>\"]+)?['\"]/gi;\n                    const matches = data.match(regex);\n                    const videoSources2 = [];\n\n                    if (matches) {\n                        const uniqueMatches = [...new Set(matches)];\n                    \n                        uniqueMatches.forEach(match => {\n                            const normalizedSrc = normalizeUrl(match.replace(/['\"]/g, ''));\n                            videoSources2.push(normalizedSrc);\n                        });\n                    }\n                    //反馈\n                    if (videoSources2.length > 0) {\n                        $('#messages').append(`<span>方法2，找到 ${videoSources2.length} 个视频。</span><br>`);\n                    }\n\n                    // 合并两种方法的结果\n                    videoSources = [...videoSources1, ...videoSources2];\n\n                    // 去重并标准化 URL\n                    const imageExtensions = /\\.(jpg|jpeg|png|gif|bmp|svg)$/i;\n\n                    videoSources = videoSources\n                                  .map(src => normalizeUrl(src.replace(/\\\\+/g, '')))\n                                  .filter(src => src) // 过滤空值\n                                  .filter(src => !imageExtensions.test(src)); // 移除图片地址\n                        \n                    videoSources = [...new Set(videoSources)];// 去重\n\n                    // 显示最终结果\n                    $('#messages').append(`<span>总共找到 ${videoSources.length} 个视频。</span><br>`);\n\n                    if (videoSources.length > 0) {\n                        $('#messages').append(`<span>成功提取到视频，找到 ${videoSources.length} 个视频。</span><br>`);\n                        videoSources.forEach((src, idx) => {\n                            $('#messages').append(`<div>视频地址:<span class=\"warn\"> ${src}</span><br></div>`);\n                            $('#video-source-select').append(`<option value=\"${idx}\">视频源 ${idx + 1}</option>`);\n                        });\n                    \n                        if (videoSources.length == 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').hide();\n                            updateVideoSource();\n                        } else if (videoSources.length > 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').show();\n                            updateVideoSource();\n                        } else {\n                            $('#video-container').hide();\n                            $('#video-url').hide();\n                            $('#video-source-container').hide();\n                        }\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未找到视频源。</span><br>`);\n                        $('#video-container').hide();\n                        $('#video-url').hide();\n                        $('#video-source-container').hide();\n                    }\n\n                    //提取图片\n                    const $imgContents = $(doc).find(config.imgSelector);\n                    const shouldSwap = config.swapImageAttributes;\n                    const newContents = updateImageSrc($imgContents.clone(), shouldSwap);\n                    $('#images').append(newContents).show();\n                    if (newContents.length > 0) {\n                        $('#messages').append(`<span>成功提取图片，共 ${newContents.length} 张。</span><br>`);\n                        newContents.each(function () {\n                            const imgSrc = $(this).attr('src') || $(this).attr('data-original') || $(this).attr('data-src') || $(this).attr('data-url');\n                            $('#messages').append(`<div>地址:<span class=\"warn\"> ${imgSrc}</span><br></div>`);\n                        });\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图片。</span><br>`);\n                    }\n\n                    //提取图片和文本\n                    const textContents = $(doc).find(config.textSelector).map(function () {\n                        const $currentContents = $(this);\n                        $currentContents.find('img + br, script, video, source, iframe').remove();\n                        $currentContents.html($currentContents.html().replace(/>\\s+/gi, '>').replace(/<\\/?br\\s*([^>]*)\\s*\\/?>/gi, '\\n').replace(/\\n+/g, '\\n'));\n                        return $currentContents.html();\n                    }).get().join('');\n                    if (textContents.trim()) {\n                        $('#text').append(`<span>${textContents}</span><br>`).show();\n                        $('#messages').append(`<span>成功提取图文。</span><br>`);\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图文。</span><br>`);\n                    }\n\n                    if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                        setTimeout(() => { \n                            canLoadNextPage = true;\n                            loadContent(currentPageIndex + 1); \n                        }, config.delayTime);\n                    } else {\n                        canLoadNextPage = true;\n                        if (autoLoadInProgress) {\n                            hideLoadingStatus();\n                        }\n                    }\n                } catch (parseError) {\n                    $('#messages').append(`<span class=\"error\">解析页面内容时发生错误: ${parseError.message}</span><br>`);\n                    handleLoadFailure(urls, index);\n                } finally {\n                    if (imageBox) imageBox.viewer.update();\n                    if (textBox) textBox.viewer.update();\n                }\n            },\n            error: function (jqXHR, textStatus, errorThrown) {\n                let errorMessage = `内容加载失败: ${urls[index]}`;\n                switch (textStatus) {\n                    case 'timeout':\n                        errorMessage += ', 请求超时';\n                        break;\n                    case 'abort':\n                        errorMessage += ', 请求被取消';\n                        break;\n                    case 'parsererror':\n                        errorMessage += ', 解析响应出错';\n                        break;\n                    default:\n                        errorMessage += `, 状态码: ${jqXHR.status}, 错误信息: ${errorThrown}`;\n                        break;\n                }\n                $('#messages').append(`<span class=\"error\">${errorMessage}</span><br>`);\n                handleLoadFailure(urls, index);\n                }\n            });\n        }\n\n        // 处理加载失败的情况\n        function handleLoadFailure(urls, index) {\n            if (!loadAttempts[urls[index]]) {\n                loadAttempts[urls[index]] = 1;\n            } else {\n                loadAttempts[urls[index]]++;\n            }\n            if (loadAttempts[urls[index]] <= config.maxLoadAttempts) {\n                const retryMessage = `第${index + 1}页加载失败，正在进行第${loadAttempts[urls[index]]}次加载！`;\n                $('#messages').append(`<span class=\"error\">${retryMessage}</span><br>`);\n                setTimeout(() => { \n                    canLoadNextPage = true;\n                    loadContent(index); \n                }, config.retryDelayTime);\n            } else {\n                const finalErrorMessage = `第${index + 1}页加载失败，已达到最大尝试次数(${config.maxLoadAttempts})！`;\n                $('#messages').append(`<span class=\"error\">${finalErrorMessage}</span><br>`);\n                if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                    setTimeout(() => { \n                        canLoadNextPage = true;\n                        loadContent(currentPageIndex + 1); \n                    }, config.delayTime);\n                } else {\n                    canLoadNextPage = true;\n                    if (autoLoadInProgress) {\n                        hideLoadingStatus();\n                    }\n                }\n            }\n        }\n\n        // 更新视频源\n        function updateVideoSource() {\n            const selectedIndex = parseInt(document.getElementById('video-source-select').value);\n            if (isNaN(selectedIndex) || !videoSources[selectedIndex]) {\n                $('#messages').append(`<span class=\"warn\">未找到有效的视频源。</span><br>`);\n                console.warn(\"Invalid or undefined video source:\", selectedIndex, videoSources);\n                return;\n            }\n\n            const selectedSource = videoSources[selectedIndex];\n            document.getElementById('video-url').textContent = `视频地址:\\n ${selectedSource}`;\n\n            const videoSourceElement = document.getElementById('video-source');\n            videoSourceElement.src = selectedSource;\n\n            const videoElement = document.getElementById('video-element');\n            videoElement.load();\n\n            $('#messages').append(`<span>更新视频源为: ${selectedSource}</span><br>`);\n            console.log(\"Updated video source to:\", selectedSource);\n        }\n\n        // 切换总页数显示状态\n        function toggleTotalPagesDisplay() {\n            if (urls.length > 1) {\n                $('#page').show();\n            } else {\n                $('#page').hide();\n            }\n        }\n\n        // 页面加载完成后执行的主要逻辑\n        $(document).ready(function () {\n            imageBox = document.getElementById('images');\n            textBox = document.getElementById('text');\n            if (imageBox && textBox) {\n                new Viewer(imageBox, { title: true, interval: 2000 });\n                new Viewer(textBox, { title: true, interval: 2000 });\n            }\n\n            const totalPagesText = config.totalPagesText;\n            const totalPages = parseInt(totalPagesText, 10) || 1;\n            const baseUrl = '{{baseUrl}}';\n\n            clearContainers();\n            $('#urls, #debug-info textarea, #video-url, #video-source-select').empty();\n            $('#urls, #messages, #debug-info, #video-url, #video-container, #video-source-container, #images, #text').hide();\n\n            buildUrls(totalPages, baseUrl);\n\n            const urlSelect = document.getElementById('url-select');\n            if (urlSelect.options.length > 0) {\n                urlSelect.value = '0'; \n\n                if (config.autoLoading) {\n                    autoLoadInProgress = true;\n                    for (let i = 0; i < urls.length; i++) {\n                        loadContent(i);\n                    }\n                } else {\n                    loadContent(0);\n                }\n            } else {\n                loadContent(0);\n            }\n\n            $('#url-select').change(function () {\n                clearContainers();\n                const selectedIndex = parseInt($(this).val());\n                loadContent(selectedIndex);\n            });\n            $('#prev-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex > 0) {\n                    loadContent(currentPageIndex - 1);\n                }\n            });\n            $('#next-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex < urls.length - 1) {\n                    loadContent(currentPageIndex + 1);\n                }\n            });\n            $('#auto-load-btn').click(function () {\n                autoLoadInProgress = true;\n                showLoadingStatus(1); \n                for (let i = currentPageIndex + 1; i < urls.length; i++) {\n                    loadContent(i);\n                }\n            });\n            $('#toggle-messages-btn').click(function () { $('#messages').toggle(); });\n            $('#toggle-urls-btn').click(function () { $('#urls').toggle(); });\n            $('#toggle-debug-btn').click(function () { $('#debug-info').toggle(); });\n        });\n    </script>\n</body>\n</html>",
    "ruleImage": "a@data-original",
    "ruleLink": "a.0@href",
    "ruleNextPage": "page||text.下一页@href",
    "rulePubDate": "[class=\"pic-text text-right\"]@text",
    "ruleTitle": "h4@text",
    "singleUrl": false,
    "sortUrl": "搜索🔍::/jiejie/index.php/vod/search.html?wd={{source.getVariable()}}\n黄瓜资源::/jiejie/index.php/vod/type/id/87.html\n155资源::/jiejie/index.php/vod/type/id/248.html\n森林资源::/jiejie/index.php/vod/type/id/117.html\n奥斯卡资源::/jiejie/index.php/vod/type/id/86.html\n百万资源::/jiejie/index.php/vod/type/id/237.html\n制服诱惑::/jiejie/index.php/vod/show/id/251.html\n中文字幕::/jiejie/index.php/vod/show/id/254.html\n美乳巨乳::/jiejie/index.php/vod/show/id/262.html\n熟女人妻::/jiejie/index.php/vod/show/id/259.html\n萝莉少女::/jiejie/index.php/vod/show/id/260.html\n强奸乱伦::/jiejie/index.php/vod/show/id/263.html\n无码专区::/jiejie/index.php/vod/show/id/249.html",
    "sourceComment": "jiejiesp.xyz",
    "sourceGroup": "4视频影视",
    "sourceIcon": "天",
    "sourceName": "1.1",
    "sourceUrl": "https://wap.jiejiesp27.xyz/"
  },
  {
    "articleStyle": 0,
    "customOrder": -10100909,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "header": "@js:\ncache.putMemory('yckdm',String.raw`\njava.toast('地址发布页 yckceo.vip');\nvar surl='https://yckceo.vip', mint=9999;\r\nlet rr = java.ajax(surl);\r\nrr = org.jsoup.Jsoup.parse(rr);\nlet rrr=rr.select('meta[name=description]').attr('content');\nfunction b(c,d){var e=a();return b=function(f,g){f=f-0x1ab;var h=e[f];return h;},b(c,d);}var i=b;function a(){var j=['put','161252hFAgZP','60KuwAjO','452607FrgcMw','39694vPAcpu','20804634VYdpiK','17ZxdOeK','3888675QVlUWv','111054tvOjuH','956336LBAxJT','yckds'];a=function(){return j;};return a();}(function(c,d){var h=b,e=c();while(!![]){try{var f=parseInt(h(0x1b2))/0x1*(-parseInt(h(0x1b0))/0x2)+-parseInt(h(0x1af))/0x3+parseInt(h(0x1ad))/0x4*(-parseInt(h(0x1ae))/0x5)+-parseInt(h(0x1b4))/0x6+-parseInt(h(0x1b3))/0x7+-parseInt(h(0x1b5))/0x8+parseInt(h(0x1b1))/0x9;if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x9db8a),cache[i(0x1ac)](i(0x1ab),rrr));\nrr = rr.select(\"#urllist a:not([href='#'])\");\nrr.length<2&&java.longToast('发布页访问异常');\nPackages.java.util.Collections.reverse(rr);\r\nlet aly = new JavaImporter(Packages.org.jsoup.Jsoup, Packages.org.jsoup.Connection);\r\nfor (char of rr) {\r\n\tlet url = char.attr(\"href\");\r\n\turl = 'https://' + String(url).replace(/^.*\\//, '');\r\n\ttry {\r\n\t\tlet st = Date.now();\r\n\t\twith (aly) {\r\n\t\t\tJsoup.connect(url)\r\n\t\t\t\t.timeout(5000)\r\n\t\t\t\t.ignoreContentType(true)\r\n\t\t\t\t.followRedirects(false)\r\n\t\t\t\t.method(Connection.Method.HEAD)\r\n\t\t\t\t.execute()\r\n\t\t}\r\n\t\tlet et = Date.now();\n\t\turl+=(cache.get('yckwb')||'');\r\n\t\tlet tm = et-st;\r\n\t\tif (tm<900) {\r\n\t\t\tsurl=url;\n\t\t\tbreak;}\r\n\t\tif (tm<mint) {mint=tm;surl=url;}\r\n\t} catch (err) {}\r\n}\ntry {\ncookie.setCookie(surl,\n(source.getLoginHeaderMap()||{}).Cookie||'');\n}catch(e){}\n//cookie.removeCookie(surl);\nsurl\r\n`);\r\n''",
    "jsLib": "qiehuanlib=[{首页:\"\"},{阅读:\"/yuedu/index/index.html\"},{书源:\"/yuedu/shuyuan/index.html\"},{书源合集:\"/yuedu/shuyuans/index.html\"},{订阅源:\"/yuedu/rss/index.html\"},{订阅源合集:\"/yuedu/rsss/index.html\"},{其它:\"/yuedu/tools/index.html\"}];\n\nfunction gengxin(){\nconst {java, source} = this;\n\tlet url0='https://gitee.com/lyc486/yuedu2/commits/main/订阅/源仓库/yck.json?browser_history=0&page=1&per=3';\n\tlet rr0=java.get(url0,{'User-Agent': 'Mozilla/5.0 (Linux; Android 14)','X-Requested-With': 'XMLHttpRequest'}).body();\n\tlet \tgxlrr = com.jayway.jsonpath.JsonPath.read(rr0, '$.list[0:3].title');\n\tlet [gxlr, gxlr2, gxlr3] = gxlrr;\n\tlet banben =   String(source.sourceComment).match(/let banben=\"([\\d\\.]+)\"/)[1];\n\tgxlr=String(gxlr).split(/^([^\\-]+)-/);\n\tgxlr[0]=='' ? '' : gxlr=['','0',gxlr[0]];\n\tlet gxts;\n\tif (gxlr[1]>banben){gxts=['更新','0,140,186'];}\n\telse {gxts= ['导入','76,175,80'];};\n\tlet htm = `data:text/html;charset=utf-8,<html>\n<head>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>订阅源更新</title>\n<style>\ntable {\n\ttext-align: center;\n\tmargin: 0 auto;\n\t}\n.ann {\n\tdisplay: flex;\n\tjustify-content: center;\n\talign-items: center;\n\theight: 50vh;\n\t}\nbutton {\n\tbackground-color: rgb(${gxts[1]});\n\tcolor: white;\n\tborder: none;\n\tborder-radius: 4px;\n\theight: 6vh;\n\twidth: 30vw;\n\toverflow: hidden;\n\t}\nbutton span {\n  cursor: pointer;\n  display: inline-block;\n  position: relative;\n  transition: 0.4s;\n}\nbutton span:after {\n  content: '>';\n  position: absolute;\n  opacity: 0;\n  top: 0;\n  right: 30px;\n  transition: 0.2s;\n}\nbutton:active span {\n  padding-right: 20px;\n}\nbutton:active span:after {\n  opacity: 1;\n  right: -40px;\n}\n</style>\n</head>\n<body>\n<table border=\"1\" cellspacing=\"0\">\n<th colspan=\"2\">最新日志：${gxlr[2]}</th>\n<tr>\n<td>仓库版本：${gxlr[1]}</td>\n<td>本地版本：${banben}</td>\n</tr>\n<tr>\n<td colspan=\"2\" style=\"text-align: left;\">往期日志：${gxlr2}<br>　　　　　${gxlr3}</td>\n</tr>\n</table>\n<div class=\"ann\">\n<a href=\"legado://import/importonline?src=https://gitee.com/lyc486/yuedu2/raw/main/订阅/源仓库/yck.json\">\n<button><span>${gxts[0]}</span></button>\n</a>\n</div>\n<a href=\"legado://import/importonline?src=https://cdn.jsdelivr.net/gh/Luoyacheng/yuedu@main/订阅/源仓库/yck.json\" style=\"font-size: 10px;\">备用链接</a>\n</body>\n</html>`;\njava.startBrowser(htm,'源仓库订阅源更新');\r\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "loginUi": "[\n    {\n    \tname: \"📌切换起始页\",\n    \ttype: \"button\",\n    \taction: \"qiehuan()\",\n        \"style\": {\n            \"layout_flexGrow\": 0,\n            \"layout_flexBasisPercent\": -1,\n            \"layout_wrapBefore\": true\n        }\n    \t},\n    \t{\n    \tname: \"🔧更新订阅源\",\n    \ttype: \"button\",\n    \taction: \"gengxin()\",\n        \"style\": {\n            \"layout_flexGrow\": 0,\n            \"layout_flexBasisPercent\": -1,\n            \"layout_wrapBefore\": true\n        }\n    \t},\n    \t{\n    \tname: \"📝登录\",\n    \ttype: \"button\",\n    \taction: \"denglu()\",\n        \"style\": {\n            \"layout_flexGrow\": 0,\n            \"layout_flexBasisPercent\": -1,\n            \"layout_wrapBefore\": true\n        }\n    \t}\n]",
    "loginUrl": "function login(){}\nfunction qiehuan(){\n\tlet nm = source.get('ycknm');\n\tif(nm==''||nm>6) {nm=0;}\n\tlet qh = qiehuanlib[nm];\n\tlet key = Object.keys(qh)[0];\n\tlet value = qh[key];\n\tcache.put('yckwb',value);\n\tjava.longToast('\\n起始页已设为\\n'+key);\n\tnm++;\n\tsource.put('ycknm',nm);\n\tjava.ajax(\"https://m.baidu.com\");\n\t}\nfunction denglu(){\n\tlet url=eval(String(cache.getFromMemory('yckdm'))).match(/^http.{4}[^\\/]+/);\n\tif (url) {\n\tjava.startBrowserAwait(url,'登录');\n\tPackages.java.lang.Thread.sleep(50);\n//\tlet ck=java.webView('<html></html>', url, \"document.cookie||'0'\");\n let ck=cookie.getCookie(url)+''; //效果和上面相同(startBrowserAwait函数运行后)，但上面是实时获取\nif (!ck.includes('token')) java.toast('💔登录失败');\nelse source.putLoginHeader(`{Cookie: \"${ck}\"}`),java.toast('🎉登录成功');\n\t\t} else java.toast('获取网站失败');\n}",
    "singleUrl": true,
    "sourceComment": "let banben=\"0.0.7\";",
    "sourceGroup": "2下载储存",
    "sourceIcon": "https://gitee.com/lyc486/yuedu/raw/master/ycktb.gif",
    "sourceName": "源仓库",
    "sourceUrl": "http@js:eval(String(cache.getFromMemory('yckdm')))"
  },
  {
    "articleStyle": 2,
    "customOrder": -10100905,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "header": "User-Agent=Mozilla/5.0 (Linux;Android 14;NX769J Build/UKQ1.230917.001;wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/120.0.6099.193 Mobile Safari/537.36&&Cookie@_ga=GA1.1.1223696036.1746402552;\n _ym_uid=1746402553591570637;\n _ym_d=1746402553;\n _ym_isad=2;\n _ym_visorc=b;\n _ga_DBB124K50K=GS2.1.s1746833053$o6$g1$t1746833355$j0$l0$h0;\n _ga_H01LFLSMK7=GS2.1.s1746833053$o6$g1$t1746833356$j0$l0$h0&&Accept@text/html,application/xhtml+xml,application/xml;\nq=0.9,image/avif,image/webp,image/apng,*/*;\nq=0.8,application/signed-exchange;\nv=b3;\nq=0.7&&Accept-Language@zh-CN,zh;\nq=0.9",
    "injectJs": "// 选择所有需要隐藏的元素（多个选择器用逗号分隔）\nconst elementsToHide = document.querySelectorAll('.nav-fixed,.respond,.content-tabs,a,blockquote,form');\n\nelementsToHide.forEach(elem => {\n  elem.style.display = 'none'; \n});\n\n\n\n// 获取视频元素\nconst video = document.querySelector('video.dplayer-video-current');\n// 左右翻转（添加样式）\nvideo.style.transform = 'scaleX(-1)';\n// 恢复正常（移除样式）\n// video.style.transform = '';",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": false,
    "ruleArticles": "article",
    "ruleLink": "a@href",
    "ruleNextPage": ".page-navigator@text.下一页@href",
    "rulePubDate": "meta[itemprop=\"dateModified\"]@content",
    "ruleTitle": "h2@text",
    "singleUrl": false,
    "sortUrl": "首页::/\n暗网吃瓜::/category/jrrg/\n暗网热搜::/category/qwrs/\n暗网爆料::/category/awcg/\n暗网反差::/category/fcll/\n暗网乱伦::/category/anwangluanlun/\n暗网校园::/category/xycg/\n每日大赛::/category/mrds/\n暗网网红::/category/dywh/\n暗网猎奇::/category/awlq/\n暗网视频::/category/sxzq/\n暗网海外::/category/hwaw/\n暗网AV解说::/category/awdz/",
    "sourceComment": "https://51awb.com/\nhttps://51aw34.com/\n\nhttps://166.run/\nhttps://heiliao365.com/\n\nhttps://www.heiliao88.com/\nhttps://18hlw.com\n\nhttps://mrds.fun/\nhttps://t.me/mrds_fun1\n\nhttps://51bl.cool/\nhttps://wyblw2.com/\n\nhttps://91spw2.com/\nhttps://91sp001.com/\n\nhttps://51cgy23.com\nhttps://www.51cg1.com/\n\nhttps://91cg.fun/\nhttps://91gua02.com/\n\nhttps://cgw321.com/\nhttps://cgwang28.com/\n\nhttps://www.51cg1.com/\nhttps://51cgy23.com/",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://www.usnlzzxy.org/usr/themes/Mirages/images/51cg.png",
    "sourceName": "51暗网",
    "sourceUrl": "https://www.usnlzzxy.org"
  },
  {
    "articleStyle": 1,
    "customOrder": -10100155,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\": \"Mozilla/5.0 (Linux; Android 10;Xiaomi 10pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36\"}",
    "lastUpdateTime": 1774474850215,
    "loadWithBaseUrl": true,
    "ruleArticles": "$..data[*]",
    "ruleContent": "$..videopath##.*\\$\n\n@js:\nurl=result;\n\nloadding=java.get(\"pic\")\n\nhtml=\n`<link rel=\"stylesheet\" type=\"text/css\" href=\"https://muiplayer.js.org/css/mui-player.min.css\" />\n\n<script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/gh/ljun223/reader3@main/js/mui-player.min.js\"></script>\n\n<script type=\"text/javascript\" src=\"https://cdn.jsdelivr.net/gh/ljun223/reader3@main/js/mui-player-mobile-plugin.min.js\"></script>\n\n<div class=\"dz\">`+url+`</div>\n\n<div id=\"mui-player\" style=\"width:100%;height:300px\"></div>\n\n<script>\n   var mp = new MuiPlayer(\t{\n \t\t  \"container\": \"#mui-player\",\n \t\t  \"src\": \"`+url+`\",\n \t\t  \"poster\":\"`+loadding+`\",\n \t\t  \"autoFit\":false,\n \t\t  \"lang\": \"zh-cn\",\n \t  \t\"height\":\"300px\",\n \t\t  plugins: [\n \t\t    new MuiPlayerMobilePlugin({\n \t\t\t    \"key\":\n \t\t\t \"01I01I01H01J01L01K01J01I01K01J01H01D01J01G01E\",\n \t\t    \t\"showMenuButton\": true,\n \t\t\t    \"pageGesture\":true,\n \t\t\t   })\n    ]\n   }); \n </script>`",
    "ruleImage": "coverpath@put:{\"pic\":\"$.coverpath\"}",
    "ruleLink": "https://77gmk8o.com/api/videoplay/{{$.id}}?uuid=1",
    "ruleNextPage": "page",
    "rulePubDate": "authername",
    "ruleTitle": "title",
    "singleUrl": false,
    "sortUrl": "@js:\n\ndata=java.ajax(\"https://77gmk8o.com/api/videosort\");\n\njson=JSON.parse(data);\n\nvar list=[];\nvar num=json.rescont.length;\nfor(var i=1;i<num;i++){\nlist+=json.rescont[i].name+\"::\"+\"https://77gmk8o.com/api/videosort/\"+json.rescont[i].id+\"?orderby=&page={{page}}\"+\"\\n\"\n\t};\n\"搜索用::https://77gmk8o.com/api/videosort/0?page={{page}}&serach={{source.getVariable()}}\"+\"\\n\"+list",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://img0.baidu.com/it/u=2908908160,2785784129&fm=253&fmt=auto&app=138&f=PNG",
    "sourceName": "葫芦视频",
    "sourceUrl": "https://77gmk8o.com"
  },
  {
    "articleStyle": 2,
    "customOrder": -2,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 1773223654663,
    "loadWithBaseUrl": true,
    "ruleArticles": ".item",
    "ruleContent": ".post-content@img@html\n\n<js>##class=\"img\"##loading=\"lazy\"</js>\n\n\n<js>##alt.*>##></js>",
    "ruleImage": "img@data-original",
    "ruleLink": "a@href",
    "ruleNextPage": "page",
    "rulePubDate": ".item-num@text",
    "ruleTitle": ".item-link-text@text",
    "singleUrl": false,
    "sortUrl": "首页::page/{{page}}/\n萝莉COS::/index.php/mntu/1/{{page}}/\n网红COS::/index.php/mntu/2/{{page}}/\n轻兰映画::/index.php/mntu/3/{{page}}/\n韩国美女::/index.php/mntu/4/{{page}}/\n丝袜美女::/index.php/mntu/130/{{page}}/\n动漫美女::/index.php/mntu/137/{{page}}/\nJK制服::/index.php/mntu/175/{{page}}/",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://www.446m.com/icon.png",
    "sourceName": "萌图社",
    "sourceUrl": "https://www.446m.com/"
  },
  {
    "articleStyle": 1,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\": \"Mozilla/5.0 (Linux; Android 12; 22041211AC Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36\"}",
    "lastUpdateTime": 1775584094755,
    "loadWithBaseUrl": true,
    "ruleArticles": ".list@li",
    "ruleContent": "<js>\nvar v = result.match(/source\\s*=\\s*[\"']([^\"']*?\\.(m3u8|mp4)\\b[^\"']*)[\"']/i);\nvar p = v ? v[1].replace(/\\\\/g,'') : '';\nvar t = '@get:{t}';\nvar d = java.getString('[property=\"video:tag\"]@content');\nvar sign1 = java.base64Decode('44CQ5aSc5piO56m644CR55qE5pKt5pS+5Zmo');\nvar sign2 = java.base64Decode('5LuF5L6b5Liq5Lq65a2m5Lmg5L2/55So77yM5Lil56aB5YiG5Lqr44CB5YCS5Y2W5Y+K5Lu75L2V6L+d5rOV6KGM5Li677yB');\nvar sign3 = java.base64Decode('5L2/55So6ICF6Ieq6KGM5om/5ouF6aOO6Zmp5LiO6LSj5Lu7');\n`<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>${t}</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:-apple-system,sans-serif;background:#f0f9ff;padding:10px}\n.v-box{max-width:800px;margin:0 auto;background:white;border-radius:12px;box-shadow:0 5px 15px rgba(0,0,0,0.1);overflow:hidden}\n.header{padding:12px;border-bottom:1px solid #eee;display:flex;flex-wrap:wrap;justify-content:space-between}\n.sign{background:#e9f7ff;padding:6px;border-radius:6px;margin-bottom:8px;font-size:14px;color:#1a73e8;width:100%}\n.title{font-size:18px;font-weight:600;margin-bottom:8px;width:100%}\n.tags{color:#5f6368;font-size:14px;flex:1;min-width:60%;word-break:break-all}\n.time{color:#5f6368;font-size:14px;text-align:right;flex-basis:35%}\n.v-wrap{position:relative;padding-top:56.25%;background:#000}\n.video{position:absolute;top:0;left:0;width:100%;height:100%}\n.footer{padding:8px;text-align:center;color:#5f6368;font-size:13px}\n.info-box{padding:15px;font-size:14px;line-height:1.6}\n.info-box p{margin:8px 0}\n.hint{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,0.7);color:#fff;padding:12px 20px;border-radius:20px;font-size:1.1rem;z-index:10;display:none}\n.controls{position:absolute;top:0;left:0;width:100%;height:4px;background:rgba(255,255,255,0.3);z-index:5;transition:opacity 0.3s}\n.progress{height:100%;background:#4a9eff;width:0}\n</style>\n</head>\n<body>\n<div class=\"v-box\">\n<div class=\"header\">\n<div class=\"sign\" style=\"text-align:center;padding:5px 0\">\n<div>${sign1}</div>\n<div style=\"text-align:left; padding-top:4px\">\n${sign2}<br>${sign3}</div>\n</div>\n<div class=\"title\">${t}</div>\n<div class=\"tags\">${d}</div>\n<div class=\"time\" id=\"timeDisplay\">00:00/00:00</div></div>\n<div class=\"v-wrap\">\n<div class=\"controls\"><div class=\"progress\" id=\"progressBar\"></div></div>\n<div class=\"hint\" id=\"hint\">快进中 &gt;&gt;</div>\n<video class=\"video\" id=\"v\" controls playsinline>\n<source src=\"${p}\" type=\"video/mp4\">您的浏览器不支持HTML5视频\n</video>\n</div>\n<div class=\"footer\">滑动调整进度 | 长按2倍速</div>\n</div>\n<script>\nvar v = document.getElementById('v');\nvar tDisplay = document.getElementById('timeDisplay');\nvar pBar = document.getElementById('progressBar');\nvar hint = document.getElementById('hint');\nvar startX = 0, startTime = 0;\nvar longPressTimer;\nvar sensitivity = 0.1;\nvar longPressTime = 500;\nvar hintDuration = 2000;\nfunction updateTime() {\nif (!v.duration) return;\nvar m1 = Math.floor(v.currentTime / 60);\nvar s1 = Math.floor(v.currentTime % 60);\nvar m2 = Math.floor(v.duration / 60);\nvar s2 = Math.floor(v.duration % 60);\ntDisplay.textContent = m1 + ':' + (s1 < 10 ? '0' : '') + s1 + '/' + m2 + ':' + (s2 < 10 ? '0' : '') + s2;\npBar.style.width = (v.currentTime / v.duration) * 100 + '%';}\nv.addEventListener('timeupdate', updateTime);\nv.addEventListener('loadedmetadata', updateTime);\nv.addEventListener('touchstart', function(e) {\nstartX = e.touches[0].clientX;\nstartTime = Date.now();\nif (longPressTimer) clearTimeout(longPressTimer);\nhint.style.display = 'none';\nlongPressTimer = setTimeout(function() {\nv.playbackRate = 2.0;\nhint.style.display = 'block';\nsetTimeout(function() { hint.style.display = 'none'; }, hintDuration);}, longPressTime);});\nv.addEventListener('touchmove', function(e) {\ne.preventDefault();\nclearTimeout(longPressTimer);\nvar diffX = e.touches[0].clientX - startX;\nvar change = diffX * sensitivity * v.duration / 100;\nv.currentTime = Math.max(0, Math.min(v.currentTime + change, v.duration));\nstartX = e.touches[0].clientX;updateTime();});\nv.addEventListener('touchend', function() {\nv.playbackRate = 1.0;\nclearTimeout(longPressTimer);});\n</script>\n</body>\n</html>`\n</js>",
    "ruleImage": "img@data-original",
    "ruleLink": "a.0@href",
    "ruleNextPage": "page",
    "rulePubDate": "{{@@.vodlist_img@html##(\\d+)-(\\d+)-(\\d+)##$0###}} | {{@@.vodlist_img@span.0@text}}",
    "ruleTitle": ".title@text@put:{\"t\":\"@@.title@text\"}",
    "singleUrl": false,
    "sortUrl": "搜索 🔍::/s/page/{{page}}/wd/{{source.getVariable()}}/\n最新::/label/hot/by/time/page/{{page}}/\n日榜::/label/hot/by/hits_day/page/{{page}}/\n周榜::/label/hot/by/hits_week/page/{{page}}/\n月榜::/label/hot/by/hits_month/page/{{page}}/\n国产 🎞::/t/1-{{page}}/\n自拍::/t/5-{{page}}/\n主播大秀::/t/6-{{page}}/\n主播诱惑::/t/36-{{page}}/\n探花::/t/7-{{page}}/\n偷拍::/t/8-{{page}}/\n乱伦::/t/8-{{page}}/\n吃瓜::/t/10-{{page}}/\n抖阴::/t/11-{{page}}/\nAV::/t/12-{{page}}/\n福利姬::/t/20-{{page}}/\n侵犯::/t/37-{{page}}/\n日韩 🎞::/t/2-{{page}}/\n日韩自拍::/t/13-{{page}}/\n日本无码::/t/14-{{page}}/\n字幕::/t/15-{{page}}/\n解说::/t/17-{{page}}/\n换脸::/t/18-{{page}}/\n欧美 🎞::/t/3-{{page}}/\n自拍::/t/21-{{page}}/\n字幕::/t/22-{{page}}/\n伦理 🎞::/t/4-{{page}}/\n三级::/t/29-{{page}}/\n日韩::/t/30-{{page}}/\n动漫 🎞::/t/16-{{page}}/\n剧集::/t/26-{{page}}/\n3D::/t/27-{{page}}/\n次元::/t/28-{{page}}/\n另类 🎞::/t/39-{{page}}/\n同性恋::/t/38-{{page}}/\n变性::/t/40-{{page}}/\n重口味::/t/23-{{page}}/",
    "sourceComment": "<声明>\n//2025.8.10 作者：夜明空\n//源社区：https://taoba.cf\n//仅供个人学习使用，严禁分享、倒卖及任何违法行为！使用者自行承担风险与责任\n</声明>\n\n//网址更新频繁，有需要请到发布页自行更新\n//发布页：\nhttps://18j.18hu.link/mdce\n18j.vip\n18zy.vip\n51zy.vip",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://18oc.life/18link/18j/images/favicon.ico",
    "sourceName": "18J-夜明空",
    "sourceUrl": "https://18oc.life/label/tag/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "6游戏直播",
    "sourceIcon": "",
    "sourceName": "工口18",
    "sourceUrl": "https://www.ryxhe.com/main.html"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2312DRAABC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "6游戏直播",
    "sourceIcon": "",
    "sourceName": "bonga cam ",
    "sourceUrl": "https://cn.bongacams4.com/female"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "花都",
    "sourceUrl": "https://a.huadudm.com/index.php"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "性癖天堂",
    "sourceUrl": "https://d2iwmjikci51k8.cloudfront.net/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "首奸",
    "sourceUrl": "https://zshunvhxx.buzz/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "",
    "sourceName": "漫画堂",
    "sourceUrl": "https://mhds7.com/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "",
    "sourceName": "成人文学网",
    "sourceUrl": "https://鶏.crwxw.buzz/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "",
    "sourceName": "八叉书库",
    "sourceUrl": "https://bachashuku.cc/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "https://wanwuu.pages.dev/\nhttps://wanwuu.com/",
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "玩物社区",
    "sourceUrl": "https://wanwuu.pages.dev/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "黑料不打烊",
    "sourceUrl": "https://wiki.wmvjojuy.cc/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "暗网",
    "sourceUrl": "https://51aw.com/category/jrrg/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "1第一道路",
    "sourceIcon": "",
    "sourceName": "xvideo -视频",
    "sourceUrl": "https://www.xvideos.com/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\t\t  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2312DRAABC) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "2下载储存",
    "sourceIcon": "",
    "sourceName": "Missav下载",
    "sourceUrl": "https://www.missav-video-downloader.online/en/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "2下载储存",
    "sourceIcon": "",
    "sourceName": "成人影片下载",
    "sourceUrl": "https://javdb.com/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "7备份",
    "sourceIcon": "",
    "sourceName": "波奇酱的礼物",
    "sourceUrl": "https://bocchi2b.top/web/"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "7备份",
    "sourceIcon": "",
    "sourceName": "yandex",
    "sourceUrl": "https://yandex.com/?ysclid=mnzp5nni7v697085903"
  },
  {
    "articleStyle": 0,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceComment": "使用需搭配加速器 不要相信里面的任何广告\n点击弹窗下方红色按钮即可跳过广告\n欢迎各位大佬对本源进行二创\n书源交流群：374309405（加群可获取福利）",
    "sourceGroup": "6游戏直播",
    "sourceIcon": "https://ogfap.com/logo.png",
    "sourceName": "成人tik需要梯子",
    "sourceUrl": "https://xxxtik.com/"
  },
  {
    "articleStyle": 3,
    "customOrder": 0,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "header": "{\n\"User-Agent\": \"Mozilla/5.0 (Android)\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "$.blocks..models[*]&&$.models[*]",
    "ruleContent": "<js>\nconst parts = baseUrl.split(',').map(function(item) { return item.trim(); });\nconst domain = parts[0].split('/').slice(0, 3).join('/');\nconst username = parts[0].split('/').pop() || parts[0];\n\nconst camAjax = java.ajax(domain + '/api/front/v2/models/username/' + username + '/cam?uniq=0');\nconst configAjax = java.ajax(domain + '/api/front/v3/config/initial');\nconst membersAjax = java.ajax(domain + '/api/front/v2/models/username/' + username + '/members?uniq=0');\n\nlet responseData = { status: \"offline\", avatarUrl: \"\", startTime: \"\", coverImg: \"\", userDescription: \"\", goalDescription: \"\", fanClubDescription: \"\", topic: \"\", username: username, stream: \"\", topBestPlace: \"\", hlsLines: [], cdn: \"\", pixelatedResolutions: [], membersCount: 0, tipMenuPriceList: [], isLive: false, tipMenuCreatedAt: \"\", websocketUrl: \"\", websocketToken: \"\", modelId: \"\" };\n\nif (camAjax) {\n    const camData = JSON.parse(camAjax);\n    const user = camData.user && camData.user.user ? camData.user.user : {};\n    const cam = camData.cam ? camData.cam : {};\n    \n    responseData.status = user.status || \"offline\";\n    responseData.avatarUrl = user.avatarUrl || \"\";\n    responseData.startTime = user.statusChangedAt || \"\";\n    responseData.userDescription = user.description || \"\";\n    responseData.goalDescription = cam.goal && cam.goal.description ? cam.goal.description : \"\";\n    responseData.fanClubDescription = cam.userFanClub && cam.userFanClub.description ? cam.userFanClub.description : \"\";\n    responseData.topic = cam.topic || \"\";\n    responseData.stream = cam.streamName || \"\";\n    responseData.topBestPlace = user.topBestPlace || \"\";\n    responseData.modelId = user.id || \"\";\n    \n    if (user.snapshotTimestamp && responseData.modelId) {\n        responseData.coverImg = \"https://img.doppiocdn.live/thumbs/\" + user.snapshotTimestamp + \"/\" + responseData.modelId;\n    }\n    \n    if (cam.broadcastSettings && cam.broadcastSettings.presets) {\n        const presets = cam.broadcastSettings.presets;\n        var allResolutions = [];\n        \n        if (presets.default && presets.default.constructor === Array) {\n            allResolutions = allResolutions.concat(presets.default);\n        }\n        \n        if (presets.pixelated && presets.pixelated.constructor === Array) {\n            allResolutions = allResolutions.concat(presets.pixelated);\n        }\n        \n        if (presets.testing && presets.testing.constructor === Array) {\n            allResolutions = allResolutions.concat(presets.testing);\n        }\n        \n        if (presets.h265 && presets.h265.constructor === Array) {\n            allResolutions = allResolutions.concat(presets.h265);\n        }\n        \n        if (presets.vr && presets.vr.constructor === Array) {\n            allResolutions = allResolutions.concat(presets.vr);\n        }\n        \n        var uniqueResolutions = [];\n        for (var i = 0; i < allResolutions.length; i++) {\n            if (uniqueResolutions.indexOf(allResolutions[i]) === -1) {\n                uniqueResolutions.push(allResolutions[i]);\n            }\n        }\n        \n        uniqueResolutions.sort(function(a, b) {\n            var numA = parseInt(a);\n            var numB = parseInt(b);\n            if (isNaN(numA)) numA = 0;\n            if (isNaN(numB)) numB = 0;\n            if (a === \"auto\") return 1;\n            if (b === \"auto\") return -1;\n            if (a === \"160p_blurred\") return 1;\n            if (b === \"160p_blurred\") return -1;\n            return numB - numA;\n        });\n        \n        responseData.pixelatedResolutions = uniqueResolutions;\n    }\n    \n    responseData.isLive = user.isOnline === true;\n    responseData.tipMenuCreatedAt = cam.tipMenu && cam.tipMenu.createdAt ? cam.tipMenu.createdAt : \"\";\n    \n    if (cam.tipMenu && cam.tipMenu.settings) {\n        responseData.tipMenuPriceList = cam.tipMenu.settings.map(function(item) {\n            return {\n                activity: item.activity || \"\",\n                price: item.price || 0\n            };\n        });\n    }\n}\n\nif (configAjax) {\n    const configData = JSON.parse(configAjax);\n    const hosts = configData.initial && configData.initial.common && configData.initial.common.hlsStreamHosts ? configData.initial.common.hlsStreamHosts : {};\n    var hlsLines = [];\n    if (hosts.A) hlsLines.push(hosts.A);\n    if (hosts.B) hlsLines.push(hosts.B);\n    if (hosts.C) hlsLines.push(hosts.C);\n    if (hosts.D) hlsLines.push(hosts.D);\n    if (hosts.E) hlsLines.push(hosts.E);\n    if (hosts.F) hlsLines.push(hosts.F);\n    responseData.hlsLines = hlsLines;\n    responseData.cdn = responseData.hlsLines[0] || \"\";\n    \n    const client = configData.initial && configData.initial.client ? configData.initial.client : {};\n    responseData.websocketUrl = client.websocket && client.websocket.url ? client.websocket.url : \"\";\n    responseData.websocketToken = client.websocket && client.websocket.token ? client.websocket.token : \"\";\n}\n\nif (membersAjax) {\n    try {\n        const membersData = JSON.parse(membersAjax);\n        responseData.membersCount = \n            (membersData && membersData.guests ? membersData.guests : 0) + \n            (membersData && membersData.spies ? membersData.spies : 0) + \n            (membersData && membersData.invisibles ? membersData.invisibles : 0) + \n            (membersData && membersData.greens ? membersData.greens : 0) + \n            (membersData && membersData.golds ? membersData.golds : 0) + \n            (membersData && membersData.regulars ? membersData.regulars : 0);\n    } catch (error) {\n        responseData.membersCount = 0;\n    }\n}\n\nJSON.stringify(responseData);\n</js>\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title></title>\n</head>\n    <style>\n        * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Microsoft Yahei', sans-serif; }\n        body { color: #333; padding: 0.1rem; min-height: 100vh; background: #f5f5f5; }\n        .app-container { display: grid; grid-template-columns: 1fr; gap: 1rem; max-width: 1200px; margin: 0 auto; }\n        .live-section { border-radius: 12px; overflow: hidden; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); border: 1px solid #eaeaea; background: #fff; }\n        .topic-section { padding: 14px 20px; border-bottom: 1px solid #eaeaea; background: #fff; display: none; }\n        .topic-label { font-size: 12px; color: #666; margin-bottom: 6px; display: flex; align-items: center; gap: 8px; font-weight: 500; }\n        .topic-content { font-size: 15px; color: #333; font-weight: 500; line-height: 1.4; }\n        .chat-section { border-radius: 12px; padding: 1rem; display: flex; flex-direction: column; height: 500px; border: 1px solid #eaeaea; background: #fff; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); }\n        .chat-messages { flex: 1; overflow-y: auto; padding-right: 0.5rem; width: 100%; }\n        .chat-messages::-webkit-scrollbar { width: 6px; }\n        .chat-messages::-webkit-scrollbar-track { background: #f0f0f0; border-radius: 3px; }\n        .chat-messages::-webkit-scrollbar-thumb { background: #c0c0c0; border-radius: 3px; }\n        .message-wrapper { display: block; margin-bottom: 0.3rem; width: 100%; }\n        .message-item { padding: 0.3rem 0.6rem; border-radius: 16px; font-size: 0.85rem; line-height: 1.3; border: 1px solid rgba(224, 224, 224, 0.6); display: block; background: #f8f8f8; color: #333; width: 100%; word-break: break-word; box-sizing: border-box; }\n        .lovense-item { border-color: #e0e0e0; background: #f8f8f8; }\n        .tip-item { border-color: #e0e0e0; background: #f8f8f8; }\n        .system-message { border-color: #e0e0e0; color: #666; font-size: 0.85rem; margin: 0 auto 0.3rem auto; background: #f8f8f8; }\n        .user-name { font-weight: 600; color: #222; margin-left: 0.4rem; }\n        .level-tag { font-size: 0.75rem; color: #666; background: #f0f0f0; padding: 0.1rem 0.4rem; border-radius: 8px; }\n        .tip-amount { color: #e74c3c; font-weight: 600; }\n        .live-header { padding: 16px 20px; border-bottom: 1px solid #eaeaea; display: flex; align-items: center; gap: 15px; background: #fff; }\n        .avatar-container { width: 56px; height: 56px; flex-shrink: 0; }\n        .avatar { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; border: 3px solid #007aff; }\n        .host-info { flex: 1; min-width: 0; }\n        .host-info h2 { font-size: 18px; margin-bottom: 6px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #333; }\n        .status-container { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }\n        .live-badge { display: inline-flex; align-items: center; background: #ff3b30; color: white; padding: 4px 10px; border-radius: 4px; font-size: 12px; font-weight: 600; letter-spacing: 0.3px; }\n        .live-badge::before { content: ''; display: inline-block; width: 6px; height: 6px; background-color: white; border-radius: 50%; margin-right: 6px; animation: blink 1.5s infinite; }\n        @keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }\n        .viewer-count { font-size: 13px; color: #666; display: flex; align-items: center; gap: 5px; }\n        .player-container { position: relative; background: #000000; overflow: hidden; }\n        .player-container:fullscreen { display: flex; align-items: center; justify-content: center; }\n        .player-container:-webkit-full-screen { display: flex; align-items: center; justify-content: center; }\n        #dplayer { width: 100% !important; height: 100% !important; display: flex; align-items: center; }\n        #dplayer video { object-fit: contain !important; }\n        .dplayer-controller { display: none !important; }\n        .dplayer-notice { display: none !important; }\n        .custom-controls { position: absolute; bottom: 0; left: 0; right: 0; padding: 12px 15px 6px; display: flex; align-items: center; justify-content: space-between; opacity: 0; transition: opacity 0.2s; z-index: 1000; pointer-events: none; }\n        .player-container.controls-visible .custom-controls { opacity: 1; pointer-events: auto; }\n        .player-container.controls-hidden .custom-controls { opacity: 0; pointer-events: none; }\n        .left-controls, .right-controls { display: flex; align-items: center; gap: 8px; pointer-events: auto; }\n        .rotate-btn { background: rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.25); color: rgba(255, 255, 255, 0.9); padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; white-space: nowrap; display: flex; align-items: center; justify-content: center; transition: all 0.15s; min-width: 52px; pointer-events: auto; }\n        .rotate-btn:hover { background: rgba(255, 255, 255, 0.25); color: white; }\n        .control-btn { background: rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.25); color: #ffffff; width: 36px; height: 36px; border-radius: 6px; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 16px; transition: all 0.15s; pointer-events: auto; }\n        .control-btn:disabled { opacity: 0.5; cursor: not-allowed; }\n        .selector-btn { background: rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.25); color: #ffffff; padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; white-space: nowrap; display: flex; align-items: center; gap: 5px; transition: all 0.15s; min-width: 65px; justify-content: center; pointer-events: auto; }\n        .selector-menu { position: absolute; bottom: 42px; background: #ffffff; border-radius: 8px; min-width: 90px; display: none; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.16); border: 1px solid #d1d1d6; overflow: hidden; z-index: 1001; pointer-events: auto; }\n        .menu-item { padding: 8px 12px; color: #333; cursor: pointer; font-size: 13px; transition: all 0.15s; border-bottom: 1px solid #eaeaea; display: flex; align-items: center; justify-content: space-between; pointer-events: auto; }\n        .menu-item:last-child { border-bottom: none; }\n        .menu-item:hover:not(:disabled) { background: #007aff; color: white; }\n        .menu-item.active { background: rgba(10, 132, 255, 0.1); color: #007aff; }\n        .menu-item.active:after { content: \"✓\"; font-size: 12px; color: #007aff; }\n        .loading-indicator { position: absolute; top: 15px; left: 15px; background: rgba(0, 0, 0, 0.8); color: white; padding: 6px 12px; border-radius: 4px; font-size: 12px; z-index: 1002; display: none; border: 1px solid rgba(255, 255, 255, 0.1); }\n        .floating-button { position: fixed; bottom: 20px; right: 20px; width: 60px; height: 60px; border-radius: 50%; background: #007aff; color: white; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3); z-index: 10000; border: none; font-size: 24px; }\n        .floating-panel { position: fixed; bottom: 90px; right: 20px; width: 400px; background: #ffffff; border-radius: 12px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); padding: 20px; z-index: 9999; border: 1px solid #eaeaea; display: none; max-height: 80vh; overflow-y: auto; }\n        .floating-panel::-webkit-scrollbar { width: 6px; }\n        .floating-panel::-webkit-scrollbar-track { background: #f0f0f0; border-radius: 3px; }\n        .floating-panel::-webkit-scrollbar-thumb { background: #c0c0c0; border-radius: 3px; }\n        .floating-panel-title { font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #333; padding-bottom: 10px; border-bottom: 1px solid #eaeaea; }\n        .floating-info-section { margin-bottom: 20px; }\n        .floating-info-section-title { font-size: 15px; color: #007aff; margin-bottom: 12px; font-weight: 600; display: flex; align-items: center; gap: 8px; }\n        .floating-info-item { margin-bottom: 12px; display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #f5f5f5; }\n        .floating-info-item:last-child { border-bottom: none; margin-bottom: 0; }\n        .floating-info-label { font-size: 13px; color: #666; min-width: 120px; }\n        .floating-info-value { font-size: 14px; color: #333; font-weight: 500; text-align: right; flex: 1; }\n        .floating-content { background: #f8f9fa; border: 1px solid #eaeaea; border-radius: 8px; padding: 12px; font-size: 14px; color: #333; line-height: 1.5; margin-bottom: 15px; }\n        .floating-price-list { display: flex; flex-direction: column; gap: 8px; }\n        .floating-price-item { background: #ffffff; border: 1px solid #eaeaea; border-radius: 8px; padding: 10px 12px; display: flex; align-items: center; justify-content: space-between; transition: all 0.2s; }\n        .floating-price-item:hover { border-color: #007aff; }\n        .floating-price-activity { font-size: 14px; color: #333; flex: 1; }\n        .floating-price-value { font-size: 14px; color: #ff3b30; font-weight: 600; }\n        @media (max-width: 768px) {\n            .floating-panel { width: 350px; right: 10px; bottom: 80px; }\n            .floating-button { width: 50px; height: 50px; font-size: 20px; right: 15px; bottom: 15px; }\n            .live-header { padding: 14px 16px; }\n            .avatar-container { width: 48px; height: 48px; }\n            .host-info h2 { font-size: 16px; }\n        }\n        @media (max-width: 480px) {\n            .floating-panel { width: 300px; }\n            .chat-section { height: 400px; }\n            .app-container { padding: 0.5rem; gap: 1rem; }\n        }\n    </style>\n<body>\n    <div id=\"config\" style=\"display:none;\">\n        <div id=\"liveData\" style=\"display:none;\">{{result}}</div>\n    </div>\n    \n    <div class=\"app-container\">\n        <div class=\"live-section\">\n            <div class=\"topic-section\" id=\"topicContainer\">\n                <div class=\"topic-label\">\n                    <i class=\"fas fa-bullhorn\"></i> 直播标题\n                </div>\n                <div class=\"topic-content\" id=\"topic\"></div>\n            </div>\n            \n            <div class=\"live-header\">\n                <div class=\"avatar-container\">\n                    <img class=\"avatar\" id=\"avatarImg\" src=\"\" alt=\"\">\n                </div>\n                <div class=\"host-info\">\n                    <h2 id=\"hostName\">正在加载...</h2>\n                    <div class=\"status-container\">\n                        <span class=\"live-badge\">直播中</span>\n                        <div class=\"viewer-count\">\n                            <i class=\"fas fa-users\"></i>\n                            <span id=\"membersCount\">--</span> 人\n                        </div>\n                    </div>\n                </div>\n            </div>\n            \n            <div class=\"player-container\" id=\"playerContainer\">\n                <div id=\"dplayer\"></div>\n                <div class=\"loading-indicator\" id=\"loadingIndicator\">正在切换...</div>\n                <div class=\"custom-controls\">\n                    <div class=\"left-controls\">\n                        <button class=\"control-btn\" id=\"refreshBtn\" title=\"刷新播放\">\n                            <i class=\"fas fa-redo-alt\"></i>\n                        </button>\n                        <button class=\"control-btn\" id=\"volumeBtn\" title=\"静音/取消静音\">\n                            <i class=\"fas fa-volume-up\"></i>\n                        </button>\n                        <div class=\"rotate-btn\" id=\"rotateBtn\">竖屏</div>\n                    </div>\n                    <div class=\"right-controls\">\n                        <div class=\"line-selector\">\n                            <div class=\"selector-btn\" id=\"lineBtn\" title=\"选择线路\">线路1 <i class=\"fas fa-chevron-down\"></i></div>\n                            <div class=\"selector-menu\" id=\"lineMenu\"></div>\n                        </div>\n                        <div class=\"quality-selector\">\n                            <div class=\"selector-btn\" id=\"qualityBtn\" title=\"选择清晰度\">默认 <i class=\"fas fa-chevron-down\"></i></div>\n                            <div class=\"selector-menu\" id=\"qualityMenu\"></div>\n                        </div>\n                        <button class=\"control-btn\" id=\"fullscreenBtn\" title=\"全屏\">\n                            <i class=\"fas fa-expand\"></i>\n                        </button>\n                    </div>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"chat-section\">\n             <div class=\"chat-messages\" id=\"chatContainer\"></div>\n        </div>\n    </div>\n    \n    <button class=\"floating-button\" id=\"floatingBtn\">\n        <i class=\"fas fa-info\"></i>\n    </button>\n    \n    <div class=\"floating-panel\" id=\"floatingPanel\">\n        <div class=\"floating-panel-title\">直播信息</div>\n        \n        <div class=\"floating-info-section\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-user\"></i> 主播信息\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">主播名称:</span>\n                <span class=\"floating-info-value\" id=\"floatingHostName\">--</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">历史最高排行:</span>\n                <span class=\"floating-info-value\" id=\"floatingTopBestPlace\">--</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">总人数:</span>\n                <span class=\"floating-info-value\" id=\"floatingMembersCount\">--</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">首次开播日期:</span>\n                <span class=\"floating-info-value\" id=\"floatingTipMenuCreatedAt\">--</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\" id=\"floatingDurationLabel\">时长标签:</span>\n                <span class=\"floating-info-value\" id=\"floatingDuration\">--</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\" id=\"floatingTimeLabel\">时间标签:</span>\n                <span class=\"floating-info-value\" id=\"floatingStatusTime\">--</span>\n            </div>\n        </div>\n        \n        <div class=\"floating-info-section\" id=\"floatingUserDescriptionSection\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-user-circle\"></i> 主播介绍\n            </div>\n            <div class=\"floating-content\" id=\"floatingUserDescription\"></div>\n        </div>\n        \n        <div class=\"floating-info-section\" id=\"floatingGoalSection\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-bullseye\"></i> 直播目标\n            </div>\n            <div class=\"floating-content\" id=\"floatingGoalDescription\"></div>\n        </div>\n        \n        <div class=\"floating-info-section\" id=\"floatingFanClubSection\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-users\"></i> 粉丝团留言\n            </div>\n            <div class=\"floating-content\" id=\"floatingFanClubDescription\"></div>\n        </div>\n        \n        <div class=\"floating-info-section\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-gift\"></i> 打赏菜单\n            </div>\n            <div class=\"floating-price-list\" id=\"floatingPriceList\"></div>\n        </div>\n        \n        <div class=\"floating-info-section\">\n            <div class=\"floating-info-section-title\">\n                <i class=\"fas fa-tv\"></i> 播放设置\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">当前线路:</span>\n                <span class=\"floating-info-value\" id=\"floatingLine\">线路1</span>\n            </div>\n            <div class=\"floating-info-item\">\n                <span class=\"floating-info-label\">清晰度:</span>\n                <span class=\"floating-info-value\" id=\"floatingQuality\">默认</span>\n            </div>\n        </div>\n    </div>\n\n    <script src=\"https://cdn.jsdelivr.net/npm/dplayer@1.27.1/dist/DPlayer.min.js\"></script>\n    <script src=\"https://cdn.jsdelivr.net/npm/hls.js@1.4.10/dist/hls.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/js/all.min.js\"></script>\n    <script>\n        const liveDataElement = document.getElementById('liveData');\n        let liveData = {};\n        \n        if (liveDataElement.textContent) {\n            try {\n                liveData = JSON.parse(liveDataElement.textContent);\n            } catch (e) {}\n        }\n        \n        const chatContainer = document.getElementById('chatContainer');\n        let chatWs = null;\n\n        function addSystemMessage(text) {\n            const systemDiv = document.createElement('div');\n            systemDiv.className = 'message-item system-message';\n            systemDiv.textContent = text;\n            chatContainer.prepend(systemDiv);\n            chatContainer.scrollTop = 0;\n        }\n        \n        function initChat() {\n            if (!liveData.modelId || !liveData.websocketUrl || !liveData.websocketToken) return;\n\n            addSystemMessage('开始连接弹幕服务器');\n            \n            const timeoutMs = 10000;\n            let connectTimeoutTimer = setTimeout(() => {\n                if (chatWs && chatWs.readyState !== WebSocket.OPEN) {\n                    chatWs.close();\n                    addSystemMessage('连接超时：未能成功连接弹幕服务器');\n                }\n            }, timeoutMs);\n            \n            if (chatWs && chatWs.readyState === WebSocket.OPEN) {\n                chatWs.close();\n            }\n            \n            chatWs = new WebSocket(`${liveData.websocketUrl}`);\n            const sendQueue = [\n                '{\"connect\":{\"token\":\"' + liveData.websocketToken + '\"},\"id\":1}',\n                `{\"subscribe\":{\"channel\":\"newChatMessage@${liveData.modelId}\"},\"id\":2}`\n            ];\n            \n            function getUserLevelTag(userData) {\n                return userData?.userRanking?.level ? `<span class=\"level-tag\">Lv.${userData.userRanking.level}</span>` : '';\n            }\n            \n            function createMessageElement(data) {\n                const messageDiv = document.createElement('div');\n                messageDiv.className = 'message-item';\n                \n                const { type, userData, details } = data.message;\n                const levelTag = getUserLevelTag(userData);\n                \n                let content = '';\n                switch(type) {\n                    case 'text':\n                        messageDiv.className += ' text-item';\n                        content = `${levelTag}<span class=\"user-name\">${userData.username}</span>: ${details.body}`;\n                        break;\n                    case 'tip':\n                        messageDiv.className += ' tip-item';\n                        content = `${levelTag}<span class=\"user-name\">${userData.username}</span>: 已支付<span class=\"tip-amount\">${details.amount}</span>代币`;\n                        break;\n                    case 'lovense':\n                        messageDiv.className += ' lovense-item';\n                        const { power, time, amount } = details.lovenseDetails.detail;\n                        const powerText = power === 'low' ? '低' : power === 'medium' ? '中' : '高';\n                        const clientLevelTag = getUserLevelTag(details.lovenseDetails.clientUserInfo);\n                        content = `${clientLevelTag}<span class=\"user-name\">${details.lovenseDetails.clientUserInfo.username}</span>: ${powerText}强度 · ${time}秒`;\n                        break;\n                    default:\n                        return null;\n                }\n                \n                messageDiv.innerHTML = content;\n                return messageDiv;\n            }\n            \n            function addMessageToPanel(messageData) {\n                const messageElement = createMessageElement(messageData);\n                if (messageElement) {\n                    const messageWrapper = document.createElement('div');\n                    messageWrapper.className = 'message-wrapper';\n                    messageWrapper.appendChild(messageElement);\n                    chatContainer.prepend(messageWrapper);\n                    chatContainer.scrollTop = 0;\n                }\n            }\n            \n            chatWs.onopen = () => {\n                clearTimeout(connectTimeoutTimer);\n                sendQueue.forEach(cmd => chatWs.send(cmd));\n                addSystemMessage('弹幕服务器连接正常');\n            };\n            \n            chatWs.onmessage = (e) => {\n                if (e.data.trim() === '{}') {\n                    chatWs.send('{}');\n                    return;\n                }\n                try {\n                    const data = JSON.parse(e.data);\n                    if (data.ping) {\n                        chatWs.send(JSON.stringify({ pong: data.ping }));\n                    }\n                    if (data.push?.channel === `newChatMessage@${liveData.modelId}`) {\n                        addMessageToPanel(data.push.pub.data);\n                    }\n                } catch (error) {}\n            };\n            \n            chatWs.onerror = (err) => {\n                const errorDiv = document.createElement('div');\n                errorDiv.className = 'message-item system-message';\n                errorDiv.textContent = '连接错误';\n                chatContainer.prepend(errorDiv);\n                chatContainer.scrollTop = 0;\n            };\n            \n            chatWs.onclose = (e) => {\n                const closeDiv = document.createElement('div');\n                closeDiv.className = 'message-item system-message';\n                closeDiv.textContent = `连接关闭 | 错误码: ${e.code}`;\n                chatContainer.prepend(closeDiv);\n                chatContainer.scrollTop = 0;\n            };\n        }\n        \n        const elements = {\n            avatarImg: document.getElementById('avatarImg'),\n            hostName: document.getElementById('hostName'),\n            refreshBtn: document.getElementById('refreshBtn'),\n            volumeBtn: document.getElementById('volumeBtn'),\n            lineBtn: document.getElementById('lineBtn'),\n            lineMenu: document.getElementById('lineMenu'),\n            qualityBtn: document.getElementById('qualityBtn'),\n            qualityMenu: document.getElementById('qualityMenu'),\n            fullscreenBtn: document.getElementById('fullscreenBtn'),\n            loadingIndicator: document.getElementById('loadingIndicator'),\n            playerContainer: document.getElementById('playerContainer'),\n            membersCount: document.getElementById('membersCount'),\n            floatingBtn: document.getElementById('floatingBtn'),\n            floatingPanel: document.getElementById('floatingPanel'),\n            floatingHostName: document.getElementById('floatingHostName'),\n            floatingTopBestPlace: document.getElementById('floatingTopBestPlace'),\n            floatingMembersCount: document.getElementById('floatingMembersCount'),\n            floatingTipMenuCreatedAt: document.getElementById('floatingTipMenuCreatedAt'),\n            floatingTopic: document.getElementById('floatingTopic'),\n            floatingTopicSection: document.getElementById('floatingTopicSection'),\n            floatingGoalDescription: document.getElementById('floatingGoalDescription'),\n            floatingGoalSection: document.getElementById('floatingGoalSection'),\n            floatingUserDescription: document.getElementById('floatingUserDescription'),\n            floatingUserDescriptionSection: document.getElementById('floatingUserDescriptionSection'),\n            floatingFanClubDescription: document.getElementById('floatingFanClubDescription'),\n            floatingFanClubSection: document.getElementById('floatingFanClubSection'),\n            floatingPriceList: document.getElementById('floatingPriceList'),\n            floatingDurationLabel: document.getElementById('floatingDurationLabel'),\n            floatingDuration: document.getElementById('floatingDuration'),\n            floatingTimeLabel: document.getElementById('floatingTimeLabel'),\n            floatingStatusTime: document.getElementById('floatingStatusTime'),\n            floatingLine: document.getElementById('floatingLine'),\n            floatingQuality: document.getElementById('floatingQuality'),\n            topicContainer: document.getElementById('topicContainer'),\n            topic: document.getElementById('topic'),\n            rotateBtn: document.getElementById('rotateBtn')\n        };\n        \n        let dp = null;\n        let isMuted = false;\n        let isFullscreen = false;\n        let hlsInstance = null;\n        let durationInterval = null;\n        let config = {};\n        let hideControlsTimer = null;\n        \n        const getStreamUrl = (lineIndex = config.currentLine || 0, quality = config.currentQuality || 'auto') => {\n            const line = config.hlsLines?.[lineIndex];\n            if (!line || !config.stream) return '';\n            \n            const pureStatus = (config.status || '').toLowerCase();\n            let suffix = '_auto';\n            \n            if (pureStatus !== 'public') {\n                suffix = '_160p_blurred';\n            } else if (quality === 'auto') {\n                suffix = '_auto';\n            } else {\n                suffix = '_' + quality;\n            }\n            \n            return `https://edge-hls.${line}/hls/${config.stream}/master/${config.stream}${suffix}.m3u8?pkey=bXorqTB5ZhP5FcpX`;\n        };\n        \n        function showControls() {\n            elements.playerContainer.classList.remove('controls-hidden');\n            elements.playerContainer.classList.add('controls-visible');\n            if (hideControlsTimer) {\n                clearTimeout(hideControlsTimer);\n            }\n            hideControlsTimer = setTimeout(() => {\n                elements.playerContainer.classList.remove('controls-visible');\n                elements.playerContainer.classList.add('controls-hidden');\n            }, 3000);\n        }\n        \n        function switchStream(url) {\n            if (!dp || !dp.video || !url) return;\n            \n            config.isSwitching = true;\n            elements.loadingIndicator.style.display = 'block';\n            showControls();\n            \n            const video = dp.video;\n            video.pause();\n            video.src = '';\n            video.load();\n            \n            if (hlsInstance) {\n                try {\n                    hlsInstance.stopLoad();\n                    setTimeout(() => {\n                        hlsInstance.destroy();\n                        hlsInstance = null;\n                        startNewStream(url, video);\n                    }, 50);\n                } catch (e) {\n                    hlsInstance.destroy();\n                    hlsInstance = null;\n                    startNewStream(url, video);\n                }\n            } else {\n                startNewStream(url, video);\n            }\n        }\n        \n        function startNewStream(url, video) {\n            video.src = url;\n            \n            if (Hls.isSupported()) {\n                hlsInstance = new Hls({\n                    enableWorker: true,\n                    lowLatencyMode: true,\n                    backBufferLength: 60,\n                    maxBufferSize: 30 * 1000 * 1000,\n                    maxBufferLength: 30\n                });\n                \n                hlsInstance.loadSource(url);\n                hlsInstance.attachMedia(video);\n                \n                hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {\n                    completeSwitch();\n                    video.play().catch(e => {});\n                });\n                \n                hlsInstance.on(Hls.Events.ERROR, (event, data) => {\n                    if (data.fatal) {\n                        switch(data.type) {\n                            case Hls.ErrorTypes.NETWORK_ERROR:\n                                hlsInstance.startLoad();\n                                break;\n                            case Hls.ErrorTypes.MEDIA_ERROR:\n                                hlsInstance.recoverMediaError();\n                                break;\n                            default:\n                                completeSwitch();\n                                break;\n                        }\n                    }\n                });\n                \n                setTimeout(() => {\n                    if (config.isSwitching) {\n                        completeSwitch();\n                    }\n                }, 5000);\n                \n            } else if (video.canPlayType('application/vnd.apple.mpegurl')) {\n                video.addEventListener('loadedmetadata', () => {\n                    completeSwitch();\n                    video.play().catch(e => {});\n                });\n                \n                video.addEventListener('error', () => {\n                    completeSwitch();\n                });\n                \n                setTimeout(() => {\n                    if (config.isSwitching) {\n                        completeSwitch();\n                    }\n                }, 5000);\n            } else {\n                completeSwitch();\n            }\n        }\n        \n        function completeSwitch() {\n            config.isSwitching = false;\n            elements.loadingIndicator.style.display = 'none';\n        }\n        \n        function initPlayer() {\n            config = { ...liveData, currentLine: 0, currentQuality: 'auto', isSwitching: false };\n            \n            const url = getStreamUrl();\n            if (!url) return;\n            \n            if (dp) {\n                dp.destroy();\n                dp = null;\n            }\n            \n            dp = new DPlayer({\n                container: document.getElementById('dplayer'),\n                live: true,\n                autoplay: true,\n                theme: '#00a1d6',\n                loop: false,\n                lang: 'zh-cn',\n                screenshot: false,\n                hotkey: false,\n                preload: 'auto',\n                volume: 0.7,\n                mutex: true,\n                controls: false,\n                video: {\n                    url: url,\n                    pic: config.coverImg,\n                    type: 'customHls',\n                    customType: {\n                        customHls: function(video, player) {}\n                    }\n                },\n                contextmenu: [],\n                danmaku: false\n            });\n            \n            const videoElement = dp.video;\n            if (videoElement) {\n                videoElement.style.pointerEvents = 'none';\n                videoElement.addEventListener('click', function(e) {\n                    e.preventDefault();\n                    e.stopPropagation();\n                    return false;\n                });\n            }\n            \n            const dplayerContainer = dp.container;\n            dplayerContainer.style.pointerEvents = 'none';\n            dplayerContainer.addEventListener('click', function(e) {\n                e.preventDefault();\n                e.stopPropagation();\n                return false;\n            });\n            \n            isMuted = dp.video.muted;\n            elements.volumeBtn.innerHTML = isMuted \n                ? '<i class=\"fas fa-volume-mute\"></i>'\n                : '<i class=\"fas fa-volume-up\"></i>';\n            \n            switchStream(url);\n        }\n\n        function refreshPlayer() {\n            if (config.isSwitching || !config.stream) return;\n            const url = getStreamUrl(config.currentLine, config.currentQuality);\n            switchStream(url);\n        }\n        \n        function switchLine(lineIndex) {\n            if (config.isSwitching || !config.hlsLines || lineIndex >= config.hlsLines.length) return;\n            config.currentLine = lineIndex;\n            elements.lineBtn.innerHTML = `线路${lineIndex + 1} <i class=\"fas fa-chevron-down\"></i>`;\n            elements.floatingLine.textContent = `线路${lineIndex + 1}`;\n            updateLineMenuHighlights();\n            elements.lineMenu.style.display = 'none';\n            \n            const url = getStreamUrl(lineIndex, config.currentQuality);\n            switchStream(url);\n        }\n        \n        function switchQuality(quality) {\n            if (config.isSwitching) return;\n            config.currentQuality = quality;\n            const displayText = quality === 'auto' ? '默认' : quality;\n            elements.qualityBtn.innerHTML = `${displayText} <i class=\"fas fa-chevron-down\"></i>`;\n            elements.floatingQuality.textContent = displayText;\n            updateQualityMenuHighlights();\n            elements.qualityMenu.style.display = 'none';\n            \n            const url = getStreamUrl(config.currentLine, quality);\n            switchStream(url);\n        }\n        \n        function formatDuration(seconds) {\n            if (!seconds) return '0秒';\n            \n            const days = Math.floor(seconds / (24 * 60 * 60));\n            const hours = Math.floor((seconds % (24 * 60 * 60)) / (60 * 60));\n            const minutes = Math.floor((seconds % (60 * 60)) / 60);\n            const secs = Math.floor(seconds % 60);\n            \n            let result = '';\n            if (days > 0) result += `${days}天`;\n            if (hours > 0) result += `${hours}小时`;\n            if (minutes > 0) result += `${minutes}分钟`;\n            if (secs > 0 || result === '') result += `${secs}秒`;\n            \n            return result;\n        }\n        \n        function updateTimeInfo() {\n            if (!config.status || !config.startTime) return;\n            \n            const pureStatus = config.status.replace(/^状态：/, '').toLowerCase();\n            const isPublic = pureStatus === 'public';\n            const startTime = config.startTime ? new Date(config.startTime).getTime() : null;\n            const now = Date.now();\n            \n            if (config.isLive && startTime) {\n                if (isPublic) {\n                    elements.floatingDurationLabel.textContent = '直播时长:';\n                    elements.floatingTimeLabel.textContent = '直播时间:';\n                    \n                    const duration = Math.floor((now - startTime) / 1000);\n                    const durationText = formatDuration(duration);\n                    elements.floatingDuration.textContent = durationText;\n                    \n                    const startDate = new Date(startTime);\n                    elements.floatingStatusTime.textContent = startDate.toLocaleString();\n                } else {\n                    elements.floatingDurationLabel.textContent = '持续时长:';\n                    elements.floatingTimeLabel.textContent = '私密直播:';\n                    \n                    const duration = Math.floor((now - startTime) / 1000);\n                    const durationText = formatDuration(duration);\n                    elements.floatingDuration.textContent = durationText;\n                    \n                    const startDate = new Date(startTime);\n                    elements.floatingStatusTime.textContent = startDate.toLocaleString();\n                }\n            } else if (startTime) {\n                elements.floatingDurationLabel.textContent = '持续时长:';\n                elements.floatingTimeLabel.textContent = '下播时间:';\n                \n                const duration = Math.floor((now - startTime) / 1000);\n                let durationText = formatDuration(duration);\n                elements.floatingDuration.textContent = durationText;\n                \n                const endDate = new Date(startTime);\n                elements.floatingStatusTime.textContent = endDate.toLocaleString();\n            } else {\n                elements.floatingDuration.textContent = '--';\n                elements.floatingStatusTime.textContent = '--';\n            }\n        }\n        \n        function startDurationUpdate() {\n            if (durationInterval) {\n                clearInterval(durationInterval);\n            }\n            \n            updateTimeInfo();\n            durationInterval = setInterval(updateTimeInfo, 1000);\n        }\n        \n        function updateFloatingPanel() {\n            const pureUsername = (config.username || '').split('/').pop() || config.username || '';\n            elements.floatingHostName.textContent = pureUsername || '未知主播';\n            elements.membersCount.textContent = config.membersCount > 0 ? config.membersCount.toLocaleString() : '--';\n            elements.floatingMembersCount.textContent = config.membersCount > 0 ? config.membersCount.toLocaleString() : '--';\n            \n            if (config.topBestPlace > 0) {\n                const rankText = `TOP ${config.topBestPlace}`;\n                elements.floatingTopBestPlace.textContent = rankText;\n            } else {\n                elements.floatingTopBestPlace.textContent = '未上榜';\n            }\n            \n            if (config.tipMenuCreatedAt) {\n                const createdAt = new Date(config.tipMenuCreatedAt);\n                elements.floatingTipMenuCreatedAt.textContent = createdAt.toLocaleString();\n            } else {\n                elements.floatingTipMenuCreatedAt.textContent = '--';\n            }\n            \n            if (config.userDescription && config.userDescription.trim() !== '') {\n                elements.floatingUserDescription.textContent = config.userDescription;\n                elements.floatingUserDescriptionSection.style.display = 'block';\n            } else {\n                elements.floatingUserDescriptionSection.style.display = 'none';\n            }\n            \n            if (config.goalDescription && config.goalDescription.trim() !== '') {\n                elements.floatingGoalDescription.textContent = config.goalDescription;\n                elements.floatingGoalSection.style.display = 'block';\n            } else {\n                elements.floatingGoalSection.style.display = 'none';\n            }\n            \n            if (config.fanClubDescription && config.fanClubDescription.trim() !== '') {\n                elements.floatingFanClubDescription.textContent = config.fanClubDescription;\n                elements.floatingFanClubSection.style.display = 'block';\n            } else {\n                elements.floatingFanClubSection.style.display = 'none';\n            }\n            \n            if (config.tipMenuPriceList && config.tipMenuPriceList.length > 0) {\n                elements.floatingPriceList.innerHTML = '';\n                config.tipMenuPriceList.forEach((tip) => {\n                    const priceItem = document.createElement('div');\n                    priceItem.className = 'floating-price-item';\n                    \n                    const activityDiv = document.createElement('div');\n                    activityDiv.className = 'floating-price-activity';\n                    activityDiv.textContent = tip.activity || '未命名';\n                    \n                    const priceDiv = document.createElement('div');\n                    priceDiv.className = 'floating-price-value';\n                    priceDiv.textContent = `${tip.price || 0} 代币`;\n                    \n                    priceItem.appendChild(activityDiv);\n                    priceItem.appendChild(priceDiv);\n                    elements.floatingPriceList.appendChild(priceItem);\n                });\n            } else {\n                elements.floatingPriceList.innerHTML = '<div class=\"floating-price-item\"><div class=\"floating-price-activity\">暂无打赏菜单</div></div>';\n            }\n            \n            startDurationUpdate();\n        }\n        \n        function initUI() {\n            const pureUsername = (config.username || '').split('/').pop() || config.username || '';\n            elements.hostName.textContent = pureUsername || '未知主播';\n            \n            if (config.topic && config.topic.trim() !== '') {\n                elements.topic.textContent = config.topic;\n                elements.topicContainer.style.display = 'block';\n                document.title = config.topic;\n            } else {\n                elements.topicContainer.style.display = 'none';\n                document.title = pureUsername || '直播间';\n            }\n            \n            if (config.avatarUrl) {\n                const prefix = 'https://static-cdn.strpst.com';\n                if (config.avatarUrl.startsWith(prefix + prefix)) {\n                    config.avatarUrl = config.avatarUrl.replace(prefix + prefix, prefix);\n                }\n                elements.avatarImg.src = config.avatarUrl;\n            } else {\n                elements.avatarImg.src = '主播';\n            }\n            \n            updateFloatingPanel();\n        }\n        \n        function initLineMenu() {\n            elements.lineMenu.innerHTML = '';\n            \n            if (!config.hlsLines || config.hlsLines.length === 0) {\n                const item = document.createElement('div');\n                item.className = 'menu-item';\n                item.textContent = '无线路';\n                item.style.opacity = '0.6';\n                elements.lineMenu.appendChild(item);\n                return;\n            }\n            \n            config.hlsLines.forEach((line, index) => {\n                const item = document.createElement('div');\n                item.className = `menu-item ${index === config.currentLine ? 'active' : ''}`;\n                item.textContent = `线路${index + 1}`;\n                item.dataset.index = index;\n                item.onclick = (e) => {\n                    e.stopPropagation();\n                    switchLine(index);\n                };\n                elements.lineMenu.appendChild(item);\n            });\n        }\n        \n        function initQualityMenu() {\n            elements.qualityMenu.innerHTML = '';\n            const pureStatus = (config.status || '').replace(/^状态：/, '').toLowerCase();\n            \n            let availableQualities = [];\n            availableQualities.push({ value: 'auto', display: '默认' });\n            \n            if (pureStatus !== 'public') {\n                availableQualities = [{ value: '160p_blurred', display: '模糊' }];\n                config.currentQuality = '160p_blurred';\n            } else if (config.pixelatedResolutions && config.pixelatedResolutions.length > 0) {\n                config.pixelatedResolutions.forEach(resolution => {\n                    if (resolution !== '160p_blurred') {\n                        availableQualities.push({ \n                            value: resolution, \n                            display: resolution \n                        });\n                    }\n                });\n            }\n            \n            availableQualities.forEach((quality) => {\n                const isActive = quality.value === config.currentQuality;\n                const item = document.createElement('div');\n                item.className = `menu-item ${isActive ? 'active' : ''}`;\n                item.textContent = quality.display;\n                item.dataset.quality = quality.value;\n                item.onclick = (e) => {\n                    e.stopPropagation();\n                    switchQuality(quality.value);\n                };\n                elements.qualityMenu.appendChild(item);\n            });\n            \n            const currentQuality = availableQualities.find(q => q.value === config.currentQuality);\n            const displayText = currentQuality ? currentQuality.display : '默认';\n            elements.qualityBtn.innerHTML = `${displayText} <i class=\"fas fa-chevron-down\"></i>`;\n            elements.floatingQuality.textContent = displayText;\n        }\n        \n        function updateLineMenuHighlights() {\n            const items = elements.lineMenu.querySelectorAll('.menu-item');\n            items.forEach((item, index) => {\n                if (index === config.currentLine) {\n                    item.classList.add('active');\n                } else {\n                    item.classList.remove('active');\n                }\n            });\n        }\n        \n        function updateQualityMenuHighlights() {\n            const items = elements.qualityMenu.querySelectorAll('.menu-item');\n            items.forEach((item) => {\n                const quality = item.dataset.quality;\n                if (quality === config.currentQuality) {\n                    item.classList.add('active');\n                } else {\n                    item.classList.remove('active');\n                }\n            });\n        }\n        \n        async function handleRotateClick() {\n            try {\n                if (!document.fullscreenElement) {\n                    await elements.playerContainer.requestFullscreen();\n                }\n                \n                if (screen.orientation) {\n                    const type = screen.orientation.type;\n                    if (type.startsWith('portrait')) {\n                        await screen.orientation.lock('landscape');\n                        elements.rotateBtn.textContent = '横屏';\n                    } else {\n                        await screen.orientation.lock('portrait');\n                        elements.rotateBtn.textContent = '横屏';\n                    }\n                }\n                showControls();\n            } catch (err) {}\n        }\n        \n        function bindEvents() {\n            elements.refreshBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                refreshPlayer();\n                showControls();\n            });\n            \n            elements.volumeBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                if (dp && dp.video && !config.isSwitching) {\n                    isMuted = !isMuted;\n                    dp.video.muted = isMuted;\n                    elements.volumeBtn.innerHTML = isMuted \n                        ? '<i class=\"fas fa-volume-mute\"></i>'\n                        : '<i class=\"fas fa-volume-up\"></i>';\n                }\n                showControls();\n            });\n            \n            elements.fullscreenBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                if (!isFullscreen) {\n                    const container = document.querySelector('.player-container');\n                    if (container.requestFullscreen) {\n                        container.requestFullscreen();\n                    } else if (container.webkitRequestFullscreen) {\n                        container.webkitRequestFullscreen();\n                    }\n                    elements.fullscreenBtn.innerHTML = '<i class=\"fas fa-compress\"></i>';\n                } else {\n                    if (document.exitFullscreen) {\n                        document.exitFullscreen();\n                    } else if (document.webkitExitFullscreen) {\n                        document.webkitExitFullscreen();\n                    }\n                    elements.fullscreenBtn.innerHTML = '<i class=\"fas fa-expand\"></i>';\n                }\n                isFullscreen = !isFullscreen;\n                showControls();\n            });\n            \n            elements.lineBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                elements.lineMenu.style.display = \n                    elements.lineMenu.style.display === 'block' ? 'none' : 'block';\n                elements.qualityMenu.style.display = 'none';\n                updateLineMenuHighlights();\n                showControls();\n            });\n            \n            elements.qualityBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                elements.qualityMenu.style.display = \n                    elements.qualityMenu.style.display === 'block' ? 'none' : 'block';\n                elements.lineMenu.style.display = 'none';\n                updateQualityMenuHighlights();\n                showControls();\n            });\n            \n            elements.rotateBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                handleRotateClick();\n            });\n            \n            elements.playerContainer.addEventListener('touchstart', (e) => {\n                if (e.target.closest('.custom-controls, .selector-menu, .control-btn, .selector-btn, .menu-item, .rotate-btn')) {\n                    showControls();\n                    return;\n                }\n                \n                if (elements.playerContainer.classList.contains('controls-hidden')) {\n                    showControls();\n                } else {\n                    elements.playerContainer.classList.remove('controls-visible');\n                    elements.playerContainer.classList.add('controls-hidden');\n                    if (hideControlsTimer) {\n                        clearTimeout(hideControlsTimer);\n                        hideControlsTimer = null;\n                    }\n                }\n            });\n            \n            document.addEventListener('click', (e) => {\n                if (!e.target.closest('.selector-btn')) {\n                    elements.lineMenu.style.display = 'none';\n                    elements.qualityMenu.style.display = 'none';\n                }\n            });\n            \n            document.addEventListener('fullscreenchange', handleFullscreenChange);\n            document.addEventListener('webkitfullscreenchange', handleFullscreenChange);\n            \n            elements.floatingBtn.addEventListener('click', (e) => {\n                e.stopPropagation();\n                elements.floatingPanel.style.display = \n                    elements.floatingPanel.style.display === 'block' ? 'none' : 'block';\n            });\n            \n            document.addEventListener('click', (e) => {\n                if (!e.target.closest('.floating-button') && !e.target.closest('.floating-panel')) {\n                    elements.floatingPanel.style.display = 'none';\n                }\n            });\n        }\n        \n        function handleFullscreenChange() {\n            const isFullscreenNow = !!(document.fullscreenElement || \n                document.webkitFullscreenElement);\n            if (!isFullscreenNow) {\n                elements.fullscreenBtn.innerHTML = '<i class=\"fas fa-expand\"></i>';\n                isFullscreen = false;\n            }\n        }\n        \n        function initializeApp() {\n            if (!liveData || Object.keys(liveData).length === 0) return;\n            \n            addSystemMessage('正在读取直播间信息');\n            \n            config = { ...liveData, currentLine: 0, currentQuality: 'auto', isSwitching: false };\n            \n            initUI();\n            initLineMenu();\n            initQualityMenu();\n            initPlayer();\n            bindEvents();\n            initChat();\n            \n            elements.playerContainer.classList.add('controls-visible');\n            showControls();\n        }\n        \n        document.addEventListener('DOMContentLoaded', initializeApp);\n    </script>\n</body>\n</html>",
    "ruleImage": "https://img.doppiocdn.live/thumbs/{$.popularSnapshotTimestamp}/{$..id}_webp",
    "ruleLink": "/{$.username}",
    "rulePubDate": "{$.isLive}观众：{$.viewersCount}人 状态：{$.status}@js:result.replace(/(状态：)public/g, \"$1公开\").replace(/(状态：)(?!公开).+/g, \"$1付费\").replace(/false.*/g, '状态：未直播').replace(/true/g, '')",
    "ruleTitle": "$.username",
    "singleUrl": false,
    "sortUrl": "全部直播::/api/front/v2/models?limit=60&primaryTag=girls\n直播推荐::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"recommended\"]]\n竖屏直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"mobile\"]]\n中文直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"tagLanguageChinese\"]]\n日本直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"tagLanguageJapanese\"]]\n韩国直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"tagLanguageKorean\"]]\n户外直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"doPublicPlace\"]]\n青少年直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"ageTeen\"]]\n俄罗斯直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"tagLanguageRussianSpeaking\"]]\nASMR直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"asmr\"]]\nCOS直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"doCosplay\"]]\n情侣直播::/api/front/models?limit=60&primaryTag=couples\n变性直播::/api/front/models?limit=60&primaryTag=trans\n新人直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"autoTagNew\"]]\n互动玩具::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"autoTagInteractiveToy\"]]\n炮机直播::/api/front/models?limit=60&primaryTag=girls&filterGroupTags=[[\"fuckMachine\"]]",
    "sourceComment": "备用：\nhttps://zh.virtualtaboo.live\nhttps://zh.spiritzone.top\nhttps://zh.stripchat.webcam\nhttps://zh.mywebcamroom.com\nhttps://zh.topcams.tv\nhttps://zh.stripchatgirls.com\nhttps://zh.stripchat.com\nhttps://zh.xhamsterlive.com\nhttps://zh.hotzcam.com\nhttps://zh.tklivechat.com\nhttps://zh.spankbanglive.com\nhttps://zh.live.91pinse.com\npkey=Iecohquahc5RieQu\npkey=bXorqTB5ZhP5FcpX",
    "sourceGroup": "6游戏直播",
    "sourceIcon": "https://i.imgs.ovh/2025/12/29/Cwo6eX.png",
    "sourceName": "Strip直播",
    "sourceUrl": "https://zh.topcams.tv"
  },
  {
    "articleStyle": 0,
    "customOrder": 2,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "header": "{\"User-Agent\":\"Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/012.002; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.0 Mobile Safari/533.4 3gpp-gba\"}",
    "lastUpdateTime": 1774456899623,
    "loadWithBaseUrl": true,
    "loginUrl": "https://yckceo.vip/",
    "ruleArticles": "class.ylist",
    "ruleContent": "head@all&&class.m-top@all",
    "ruleLink": "a@href",
    "rulePubDate": "{{@@h2@p@text}} {{@@tag.span@text&&tag.span.2@title}}\n@js:result.replace(/\\n/g,'  ').replace(/\\s+[23]\\.X/,'').replace(/用户[: ：]+/,'👤').replace(/ 下载[: ：](\\d+)\\s*UID[:：](\\d+)/,'(UID: $2)  📥$1').replace(/下载[：: ]+/,'📥').replace(/源数量[：:](\\d+)/,'📝$1个源')",
    "ruleTitle": "名称：{{//h2/a[1]/text()##http.*}}\n网址：{{//h2/a[1]/text()##.*(http)##$1}}\n@js:result.replace(/([\\s\\S]{4,}?)(?:\\s+)?\\1/g, '$1')",
    "singleUrl": false,
    "sortUrl": "📖书源::/yuedu/shuyuan/index.html?page={{page - 1 == 0 ? \"\": page}}\n🔰订阅源::/yuedu/rss/index.html?page={{page}}\n📖书源合集::/yuedu/shuyuans/index.html?page={{page}}\n🔰订阅源合集::/yuedu/rsss/index.html?page={{page}}\n\n🔎搜书源::/yuedu/shuyuan/index.html?keys={{svg=String(java.base64Encode(`<svg width=\"1190\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"100%\" height=\"100%\" fill=\"#ffffff\"/><text x=\"200\" y=\"100\" font-family=\"Arial, sans-serif\" font-size=\"70\" fill=\"#333\" font-weight=\"bold\">请输入关键词</text></svg>`));if(page==1){let a=\"\";try{a=java.getVerificationCode('data:image/svg+xml;base64,'+svg);}catch(e){java.log(e)};if(a==\"\"){a=source.getVariable()}source.setVariable(a);a}else{source.getVariable()};}}&uid=&order1=time&order2=1&ver=&faxian=&sousuo=&x18=<,&page={{page}}>\n🔎搜订阅::/yuedu/rss/index.html?keys={{svg=String(java.base64Encode(`<svg width=\"1190\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"100%\" height=\"100%\" fill=\"#ffffff\"/><text x=\"200\" y=\"100\" font-family=\"Arial, sans-serif\" font-size=\"70\" fill=\"#333\" font-weight=\"bold\">请输入关键词</text></svg>`));if(page==1){let a=\"\";try{a=java.getVerificationCode('data:image/svg+xml;base64,'+svg);}catch(e){java.log(e)};if(a==\"\"){a=source.getVariable()}source.setVariable(a);a}else{source.getVariable()};}}&uid=&order1=time&order2=1&ver=&faxian=&sousuo=&x18=<,&page={{page}}>\n👤搜书源(UID)::/yuedu/shuyuan/index.html?keys=&uid={{svg=String(java.base64Encode(`<svg width=\"1190\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"100%\" height=\"100%\" fill=\"#ffffff\"/><text x=\"200\" y=\"100\" font-family=\"Arial, sans-serif\" font-size=\"70\" fill=\"#333\" font-weight=\"bold\">请输入UID</text></svg>`));if(page==1){let a=\"\";try{a=java.getVerificationCode('data:image/svg+xml;base64,'+svg);}catch(e){java.log(e)};if(a==\"\"){a=source.getVariable()}source.setVariable(a);a}else{source.getVariable()};}}&order1=time&order2=1&ver=&faxian=&sousuo=&x18=<,&page={{page}}>\n👤搜订阅(UID)::/yuedu/rss/index.html?keys=&uid={{svg=String(java.base64Encode(`<svg width=\"1190\" height=\"300\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"100%\" height=\"100%\" fill=\"#ffffff\"/><text x=\"200\" y=\"100\" font-family=\"Arial, sans-serif\" font-size=\"70\" fill=\"#333\" font-weight=\"bold\">请输入UID</text></svg>`));if(page==1){let a=\"\";try{a=java.getVerificationCode('data:image/svg+xml;base64,'+svg);}catch(e){java.log(e)};if(a==\"\"){a=source.getVariable()}source.setVariable(a);a}else{source.getVariable()};}}&order1=time&order2=1&ver=&faxian=&sousuo=&x18=<,&page={{page}}>",
    "sourceComment": "by：旅途\n改：歌行灯\n弹窗搜索的代码是从关耳大大那抄的\n————————————\n【地址失效的解决方法】\n若地址失效导致订阅源失效，可于登录处进入源仓库最新地址发布页，从发布页复制最新可用地址粘贴到源URL处，然后退出重进即可。\n————————————\n【如何搜索】\n点击（或下拉）标有🔎或👤的列表，会弹出提示框，填写关键词或UID即可。也可直接在源变量处填写关键词/UID（记得保存并刷新分类）\n（昵称后面的括号里那串数字就是UID，注意不要填“UID:”这几个字符，只用填数字）\n如果你填的是源名称，那么结果在🔎处查看；如果你填的是源作者的UID，那么结果在👤处查看。\n阅读Sigma版可点击右上角搜索按钮，输入关键词搜索书源。\n————————————\n修复源URL与源名称一样时重复显示4遍的问题（2026.2.3@歌行灯）",
    "sourceGroup": "2下载储存",
    "sourceIcon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWEAAAFhBAMAAABT0QbkAAAAAXNSR0IArs4c6QAAACRQTFRFLzY8R3BMLTQ6LjU7oMxJm8dElsI/kb05jLg0hrMvb446T2M71eCsLgAAAAR0Uk5T/wBQxEskO5YAAA+JSURBVHja1NXBbdswFMbxT5KLIOlFlRaQ0AWoegEfyMCoLz0wG2SEDtARfA168cED9NABq9KMbMsSE+gRzHt/2D4+/PQsgvgSrForhZQVxboNikqEuAofU9GGxARvcnNYvMbHtg6IQwtmtOawuAaHuveLv4JH3wLiMZgbOSxuwKf8PeIanOreFlfgVfuWuFJgRw6LFbhVhMUl+JWFxBU41gbEChwr5sU1eNbNisG1OXEJrnUzYvBtWlyCb9mkGJybEpfgXDYhVmDdrbgG77obsQLvirG4AvfakbgB9/KRGPy7FpfgX3YlbsC//FJcQULthbiGhLoLcQMJ5RdiyOgsriGjbhCXkFE2iCGlV3EFKbVeXENKnRc3kFLuxQpSKrwYcjqJa8ipc+IScsqcuIGccidWEJQTQ5q4gqTaXlxDUlkvLsWJG0gq78UKkip6MWQlUVxBVg1qzPb5ZbrfiNTDy3R7zKdQBsR6ukdEaqWn2yDQErH+gzgdk4kPiJNOJt6AEHl+s2DiDlG6WyZWC8QaUVqJEx8Tin8hRs/LxFgi3sQ5eAnF3xGh+5TiLSK0SiCOe+sdk4oPoGeTijcxDl5S8Q7k7tKKH0FulVasQe6YWLwHtefE4g394KUV02+9+9TiLYh9Siym33rH5OIDaD0lFhv9A7R08h3vqDee0Ta+eGamNdpqE+HGM9N/nyXt2Pa88SfGrXc0Dnw73BB3bOd2bO0elH5q09ts9B073mgJ/imMG0t74ez/6dfzDW3Hp3HjV8K4aEfvwT268fOuXglrKTu2ZmrHDm63tIPnpxinHoaf9MvFw5RLsNH+MUDo70n5Ot3xh+1QduyH6LPXo622pFvPnnfsztowP8aO+6/PDT5vhnL0tB3Ome0b5hv3VhPEPif3x7rP/VhDOHr3fpK3Dht+or7Hboz/ng+d37b9R2wZ48YNQ0G0C5C91wApXfyhsXDjhoWRJk2O4CPsUXK/wMPPT8u7sKH/19CINCkZGIyfNKAfK/9qDitfTItPoNw8zY2r4y6deOulbfdmleYZYYSmFDdmZkS+ehcSlIscjWsPEA/5xJ+qgkL1DWFJqIuJBdhph8TkKX3iGYev+aLVXDXGdDdpRR/PfqVPPArwCuvyJxXGDB8sDIt71vgfiA3ksNZaSLzMKLMYY0mfet0ZMOqmTawlxkJAYDHQ0Ew7AzRGWKcce2OBsbk8txZpPEtW76dybcwYRKrf8ZSRVGQX9OwxeeLRSPC9mRHa6hcVxgyeBGSKIerbZrJ4HtgpO4nBmGCdMRZjYMPYctV71VesyBJG47S1ImMzCsFibFyMaQ85EMpquhQRnM4ig3xi+SzGTiAYG1PVO5Eemb7MrMO0xBjxriKrEXOQ53TxaOaThKzDFFZjbEZMENqHjGCyeCJJaGosY7D6HUtYjCfigSNTvb9uqcvk7QD8DhXGMopvOSAH4+eELc1oQZizgPdh/KWeMsX7XN+c+Jwo3rGJmSjewYn3V+9yQOKaOQ9IXKre6ejEL3tNfxydmIniHZC4Ur3XoxP3P7Xi3T9xY78afumOv3cW79rRx7i0LSTunddqmlPnexWva5YZX8MIZ7/re4t3m/DE0KuMb8JomrnqXRpvq7FrVhl/JNHYg3Fvb7fteZdnJ2XSN769ibEnLzCWR19D0otrLXfqndhbUPUh6e8QkhrjgXH9lCjjNvWys3juI8v/tJaxchQxEESVeMHwfZ6E5AKmjX05VWRExI6IL+HiS9jvo7Y127NVSzCLuClrNVaVWq0njWXnt0f/80Pdf3esq8DWP9Eyt0OFt0wKVWOvhMF8hHH45IF5fNJ2bOhy7F/NcEWoFFEiPAOMdRuYbFNTeujV45yU6nw9IoSHGMdN0Cm6OHi284HCI9pgHN1W1IcZd8tdjDkF2dL4gdJ7oN8gILHkG4jGGYuBQGz3YAcKr4slWffPV4sT1CJDjLd3lmq/tgca+aVeeN4ln7oe3f9OEpEM3GOHw8y8B/PJls7BLvL6q4c1Vj3Hl2npqGY9gQSPO6YMpSMcj66ARXIuF54rhOJ1kraWGmDcObALrB+xktUyKJfeO209sZ5mHZlOc4AxurJDBNpXd2iwr4Oq4LxaQkBw2NvMdKMKOw0wDsvJpV11T7QQqqX3EwZGnpG32ZjK8hjj8JtEvU3QVRGc70VBiHEqttk9b8Vo5Tkgy9G1R5jGVsbnauHBImTvExm7XPsgY/nS5Vu2kX4D2mtNb4KhhwN9Mk7JOGQxfo+TscFa469gg/f2VC08mCImX5ZRrFvHMGOGs7EztDbnkKE33OqFp+Bku7Urwj01GQOOO1y4y3NrkwsujKNWhAJA5x+TX5IAz44fG2UMo2enXmuPUAjLuVR4K8KM5bm8OnxljFHGFOKPzHGU42YwJ2jYt4rce2R0xL54u4JB8sOOt/LO1FprP3IHazyXCk+Ocu7b4jgR27hjXrxQItQWUFQqTCuvnmBuXcewFvpPjFllucTELWjUyKog9ySGCjr2HeRhx9tzvLH0TCORnktqti+8RO8SG3asCMcN+yi8eg+GXZzkWHFvx4pK4e3jwnfl/o7nv4/XCy9n3Z/x80Jlwi4Krx728dLuy1jn+AGFRSpiZzq+N2ON73BVXry9s/sz5iJ/qi9jpdaNKAwfYCaWTIPgBWDyApCXSUtz0UzSUFnLdeMqWkGjKlcyjapc6FzF3LeLo2jWRP/Z9drWSqt/3O3K++nzOXuAeZXDGs898ZdK00RfzK3HP1Mv/OGQWA23Cbewf+PFfRDHNVj4gJkf2Hg065R41k6jEhd2Tb0JPjK7d0CMWWhOiR/ImJ90jUcPbolnNbFx6tlPPHJOHCvHnLFH0ob/7Z9cEAPyrOYyTj37xnNHjCbVCirjE3Jf5YA4xjTH/DmDJMbGizEV1fkVVzrtvEeyaj37xjt37ljrzDj1ZhjRLMWYTidIQxziUjzf690f5uoQyBGOH1pRjolZMky9CVdfeEiToxxDHrU/80NiaDymUSsnjiHK8d+4ZGi9v2IMHOKkjreTbcL6t2+8+In6qONPjqd25ac8wvSck4s6TiBbjwlG23phglmoQzCPBxPPINsv+xZj9I2HqdQhmMOJE0NTrPFtZrrW+x5jTIcc4dhQFZO4vRbHOfFJME/UZIqHdOt4rk5Cx8n9Id/TrWOMOolijKb1AlOpTrutY8yWeJZgCMIXUCKqrWOMI8frGLPiG28GSWgAx5MEw7deyl3dJseOiKfa+YKNh1/TG/Hsd8OdFdfqbCbeLIdVZ46/ksq3BJnZxktQctUf8TOprMEcP/W+I3BCrohjyFcyt57txBukKqZMId9bfcvnbUGPxBQzy7Z/aqpMXBP/Bj83X6BGpNkKlvtxvE4wK6bxMDSIY/6whdXEc02MXW4/rvjBOZRj0leN+bXyYRzzU0/A/3gJpuqTOCO71jM33mCOA4upJ7nvGMYxX6OifRoH1L9j+9bjJ16fxAKI2dYzA60GdLxOIYpH23iidZekbh2LHQaFyAkuQFPdTFLnju1bzzzxlGO3xKkgi9Yzv1JOvdaxpF0/+pNd4ynHolPiVLQ/Lcdr3PI/orWADQm1HOOWw4nxu1q3GwXMloq2SXH5a4tY4JYjHOO3tYinsEUk97SN2ClwkvbrmGBLkj5/nnhYFHm7KtJeHVOKjjNSCRjHK6iKfh2vwdDn1vqeokAa2HEAhkSSf7r82suq8baOe67jqRBtx9sDz4WA5Rdw3OVdIXY7pvbvLkTyvL1JUljOnTqWmIxaKQx7JhKjGs+wZ3E4sYCA4w+BWVGzlmKoTZxiDidOMeA4TCGyatakgDwDscAc4RgDjqcSoupQu2SuCseOSWDmev25jWO3dUwMlqA6gWRK3HEdSwg6/oA9QjQrQkKIBr8rKEDHzW9fpJBn8sAxtl4qF80Loz2GuFPHUqStDxITbJJi2bwKrORILFPYtuh25kHeNLsCiVk5r+N2TyExtl7akH1IDEGCjqtCpi1khjiUmIr/i+OZWMeiyzq2qApsPSEfYeLpUAKZdukYwnUeyXZ/SfnCjm+Zk+s6lgDDERegWD7pGw/ruO+7omYDZLbxMrJ07J4YkuVc4y25h4cgPmcP5Un8cMzBzaeceE8c81Mv5BrPE8d8k71JDHnjOOQ2chPPG8dTaZWFP45JWiX3xTFOPT7ZyiPHgRUxDeK4JMvWwyw1L1tAenB8jsdict5xNohjkhB24rmv4yJrfzJi8wYb4ZOteMfM3j4c49TDUC+OCzBAbMKdilXjgWM843DiTMr2uRrH0128qvEYx7C3D8dU7ACWstIQZ5t06DizdEyF2fEmK53jQkqXjnXEgdkxPOjKcWbtONjleK591c3qEHV8nhmBZZFrXzWDY3pxTOY5ncmqF8cZYmiJ3zJj5Epfx3BMfnhVtI81EH8UxpSkd1xkrRzuuGRCmoSlIUXxSnrHsP1wx/u4mpYZxEZbmBWQw4kZCC0xlaaaKCt9VeApRzguIQbizFAV5crgGHb35Dg0OiZDHcPunhyHJscveuKyzHp3jH2K1nx0TKU+sjIUU6eODQWJec+0KVeGqoDLojyCGJIZiH+U+pDBMR5yTB3vdbYe+JUMjjG52ymN2zELw3sOSEyZlrgyOC4GJNYCF+SNY7yo2E9J/tWxufVeTA8xb+iK2L71cl8dk7bxfK1jei/5kH+OzVOvIG8dh5qJ56Fjc+vl/jomTeN56NjceuSx44An9thxyDaex475J/KOHd92SUxs43nsmG898trxj72fCAcmnjKN5zEx/0jeNfF1p8TENF7XdXzRLfH7vg+EromX+wIs+yY+Wtmr58T4TN458VW3xASN1zHxLV3uIH7ffpZYlnzrLf97bolvyBOrByyIrynq2HF41P5lTW4ivnBN/ErHVgUS39KYcrYhvqYx5XRDfEFjysmG+IrGlLsN8SWNKTcb4ojGlOhf4tuxEY/qsjitiS/GdFXUxFdjuipq4mhMZVwTj6j1zmriMbXeaU08pkK+a4gvxzPxGuJoRI3XEF+MpYwV8dVYylgRR6MpCkV8PY6iUMRjKYsTRTyW++1GEY9kUJ9Fingk99uJIh7LbREp4pHcFqct4iv/x0eLOLr1v+8U8Th67wSIfZccIfGF54qROPJbMRB7LvkUiH2XHPHEV55XMRJH/t7FQOy55DsgVrn1XDESX5KPuUFiv2+4kwiI/a6LswiIPa+LGyAGZA+BkdjfK+4uQmLItV9/TyAx5mfyJb9EHLFvyAiMxJgrv2oYiTGXnt0SSIy59aznkBg1D8l8BoKBeGBm5NUS/wMtJQR5NY0DewAAAABJRU5ErkJggg==",
    "sourceName": "源仓库\n(看注释)",
    "sourceUrl": "https://www.yck2026.top",
    "variableComment": "请填写搜索关键词或UID\n若列表没有刷新请手动 右上三个点【刷新分类】\n"
  },
  {
    "articleStyle": 0,
    "coverDecodeJs": "java.createSymmetricCrypto(\"AES/CBC/NoPadding\",\"f5d965df75336270\",\"97b60394abc2fbe1\").decrypt(result)",
    "customOrder": 3,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\":\"Mozilla/5.0 (Linux; U; Android 13; zh-Hans-CN; PFJM10 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/135.0.4896.58 Quark/6.13.6.581 Mobile Safari/537.36\",\n\"Accept-Language\":\"zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7\"}",
    "lastUpdateTime": 1775584744388,
    "loadWithBaseUrl": true,
    "ruleArticles": "#body>.container>.row>div[role=\"main\"]>article:not(:has(meta[content=\"广告\"]))>a",
    "ruleContent": "@js:\nlet urls = [];\nlet resultStr = String(result);\n\nlet getM3u8 = (html = resultStr) => {\n    let url = /(https?:[^'\"\\s]*?\\.m3u8[^'\"\\s]*)/g;\n    let urlSet = new Set();\n    for (let match of (html.matchAll(url) || [])) {\n  \t   let ul = match[1].replace(/\\\\/g, \"\");\n  \t   urlSet.add(ul);\n    \t};\n    return Array.from(urlSet);\n};\n\n let updateProgress = (current, total) => {\n    let percentage = Math.round(current / total * 10000)/100;\n    let blocks = Math.floor(percentage / 10);\n    let progressBar = \"█\".repeat(blocks) + \"░\".repeat(10 - blocks);\n    java.longToast(`【加载进度】\\n${progressBar} \\n${percentage}%`);\n};\n\nif (/点我/.test(result) && /查看详情/.test(result)) {\n    let list = java.getElements('@@#post>article>.post-content>p>a');\n    let links = Array.from(list).slice(0,-1);\n    let tempUrls = []; \n    links.forEach((link, index) => {\n        updateProgress(index + 1, links.length);\n        \n        let href = String(link.attr('href'));\n        let fullUrl = `${source.key}${href}`;\n        let doc = String(java.ajax(fullUrl));\n        let pageUrls = getM3u8(doc);\n        if (pageUrls.length > 0) {\n            tempUrls = tempUrls.concat(pageUrls);\n        }\n        if (index === links.length - 1) {\n            urls = tempUrls;\n        }\n    })\n} else {\n    urls = getM3u8();\n};\n\n`<html>\n    <head>\n        <meta name=\"viewport\" content=\"width=device-width\">\n        <style>\n            body {\n                margin: 0;\n                font-family: Arial, sans-serif;\n                background: linear-gradient(135deg, #ece9e6, #ffffff);\n                display: flex;\n                flex-direction: column;\n                align-items: center;\n                justify-content: flex-start;\n                padding: 20px;\n            }\n            .container {\n                width: 100%;\n                max-width: 800px;\n                background: #fff;\n                border-radius: 10px;\n                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n                overflow: hidden;\n                margin-bottom: 20px;\n            }\n            h3 {\n            \t    text-align: center;\n                margin: 0;\n                padding: 10px 20px;\n                font-size: 0.9em;\n                background: #333;\n                color: #fff;\n                border-radius: 10px 10px 0 0;\n            }\n            .video-container {\n                width: 100%;\n                background: #000;\n                position: relative;\n            }\n            video {\n                width: 100%;\n                height: auto;\n                display: block;\n            }\n            .info-container {\n                padding: 20px;\n            }\n            .info-container p {\n                margin: 10px 0;\n                color: #555;\n            }\n            .info-container p span {\n                font-weight: bold;\n                color: #000;\n            }\n            .nav-container {\n                display: flex;\n                justify-content: space-between;\n                align-items: center;\n                padding: 15px 20px;\n                background: #f5f5f5;\n                border-top: 1px solid #ddd;\n            }\n            .nav-button {\n                padding: 10px 20px;\n                background: #007bff;\n                color: white;\n                border: none;\n                border-radius: 5px;\n                cursor: pointer;\n                font-size: 14px;\n            }\n            .nav-button:disabled {\n                background: #6c757d;\n                cursor: not-allowed;\n            }\n            .page-select {\n                padding: 10px 15px;\n                border: 1px solid #ddd;\n                border-radius: 5px;\n                font-size: 14px;\n                background: white;\n                min-width: 120px;\n            }\n            .video-info {\n                text-align: center;\n                padding: 10px;\n                background: #f8f9fa;\n                border-bottom: 1px solid #ddd;\n                font-size: 14px;\n                color: #666;\n            }\n        </style>\n    </head>\n    <body>\n        <div class=\"container\">\n        <h3>当前播放: 第<span id=\"currentVideo\">1</span>集 / 共${urls.length}集</h3>\n            <div class=\"video-container\">\n                <video controls autoplay name=\"media\" id=\"videoPlayer\">\n                    <source src=\"${urls[0] || ''}\" type=\"application/x-mpegURL\">\n                </video>\n            </div>\n            <div class=\"nav-container\">\n                <button class=\"nav-button\" id=\"prevBtn\" onclick=\"changeVideo(-1)\">上一集</button>\n                <select class=\"page-select\" id=\"pageSelect\">\n                    <!-- 选项将通过JavaScript动态生成 -->\n                </select>\n                <button class=\"nav-button\" id=\"nextBtn\" onclick=\"changeVideo(1)\">下一集</button>\n            </div>\n            <div class=\"info-container\">\n            </div>\n        </div>\n\n        <script>\n            // 视频地址数组和当前索引\n            const videoUrls = ${JSON.stringify(urls)};\n            let currentVideoIndex = 0;\n            \n            // 获取DOM元素\n            const video = document.getElementById('videoPlayer');\n            const prevBtn = document.getElementById('prevBtn');\n            const nextBtn = document.getElementById('nextBtn');\n            const pageSelect = document.getElementById('pageSelect');\n            const currentVideoSpan = document.getElementById('currentVideo');\n            \n            // 生成下拉菜单选项\n            function generateSelectOptions() {\n                let optionsHtml = '';\n                for (let i = 0; i < videoUrls.length; i++) {\n                   optionsHtml += '<option value=\"' + i + '\">第' + (i + 1) + '集</option>';\n    };\n                pageSelect.innerHTML = optionsHtml;\n             }\n            \n            // 更新按钮状态和显示\n            function updateButtons() {\n                prevBtn.disabled = currentVideoIndex === 0;\n                nextBtn.disabled = currentVideoIndex === videoUrls.length - 1;\n                pageSelect.value = currentVideoIndex;\n                currentVideoSpan.textContent = currentVideoIndex + 1;\n            }\n            \n            // 切换视频\n            function changeVideo(direction) {\n                const newIndex = currentVideoIndex + direction;\n                if (newIndex >= 0 && newIndex < videoUrls.length) {\n                    currentVideoIndex = newIndex;\n                    video.src = videoUrls[currentVideoIndex];\n                    video.load();\n                    updateButtons();\n                }\n            }\n            \n            // 选择特定视频\n            function selectVideo(index) {\n                const newIndex = parseInt(index);\n                if (newIndex >= 0 && newIndex < videoUrls.length) {\n                    currentVideoIndex = newIndex;\n                    video.src = videoUrls[currentVideoIndex];\n                    video.load();\n                    updateButtons();\n                }\n            }\n            \n            // 初始化按钮状态\n            generateSelectOptions();\n            updateButtons();\n            \n            // 绑定下拉菜单事件\n            pageSelect.addEventListener('change',function() {\n               selectVideo(this.value);\n             });\n            \n            // 触摸控制相关代码\n            let touchStartX = 0;\n            let touchStartY = 0;\n            let touchStartTime = 0;\n            let isLongPress = false;\n\n            // 滑动快进\n            video.addEventListener('touchstart', (e) => {\n                touchStartX = e.touches[0].clientX;\n                touchStartY = e.touches[0].clientY;\n                touchStartTime = Date.now();\n                isLongPress = false;\n            });\n\n            video.addEventListener('touchmove', (e) => {\n                const deltaX = e.touches[0].clientX - touchStartX;\n                const deltaY = e.touches[0].clientY - touchStartY;\n\n                // 如果是水平滑动，且未进入长按状态\n                if (Math.abs(deltaX) > Math.abs(deltaY) && !isLongPress) {\n                    const duration = video.duration;\n                    const seekTime = video.currentTime + (deltaX / 100); // 每滑动100px快进1秒\n                    video.currentTime = Math.min(Math.max(seekTime, 0), duration);\n                }\n            });\n\n            // 长按快进\n            video.addEventListener('touchend', (e) => {\n                const touchEndTime = Date.now();\n                const touchDuration = touchEndTime - touchStartTime;\n\n                // 如果长按时间超过500ms，进入长按快进状态\n                if (touchDuration > 500) {\n                    isLongPress = true;\n                    // 在长按状态下，根据滑动距离快进\n                    const deltaX = e.changedTouches[0].clientX - touchStartX;\n                    const duration = video.duration;\n                    const seekTime = video.currentTime + (deltaX / 100); // 每滑动100px快进1秒\n                    video.currentTime = Math.min(Math.max(seekTime, 0), duration);\n                } else {\n                    isLongPress = false;\n                }\n            });\n\n            // 防止默认行为（如页面滚动）\n            video.addEventListener('touchmove', (e) => {\n                e.preventDefault();\n            });\n        </script>\n    </body>\n</html>`",
    "ruleImage": "@js:\nvar text = java.getString('script@html');\nvar match = text.match(/loadBannerDirect\\('([^']+)'/);\nvar img = match ? match[1] : '';\nimg;",
    "ruleLink": "href",
    "ruleNextPage": "page",
    "rulePubDate": "{{@@.wraps@text}}{{@@.post-card-info span@text##\\n}}",
    "ruleTitle": "h2@text",
    "singleUrl": false,
    "sortUrl": "首页::/page/{{page}}/\n每日大赛::/category/mrds/{{page}}/\n搜索::/search/{{source.getVariable()}}/{{page}}/\n主题大赛::/category/ztds/{{page}}/\n热搜吃瓜::/category/rstt/{{page}}/\n校园学生::/category/xazd/{{page}}/\n必撸大赛::/category/blyp/{{page}}/\n反差泄密::/category/fctg/{{page}}/\n网红黑料::/category/mhds/{{page}}/\n猎奇重口::/category/lqdp/{{page}}/\nAV看片::/category/jdsj/{{page}}/\n明星大赛::/category/mxwh/{{page}}/\n动漫之家::/category/smdh/{{page}}/\n影视国漫::/category/dypd/{{page}}/\ncos写真::/category/mtds/{{page}}/\n声控ASMR::/category/ysds/{{page}}/\n寸止挑战::/category/czds/{{page}}/\n混剪PMV::/category/hjds/{{page}}/\n原创投稿::/category/tgds/{{page}}/\n欧美精品::/category/omjp/{{page}}/\n全网参赛::/category/qwcs/{{page}}/",
    "sourceComment": "发布页: https://www.njttvylz.cc\n最新网址: https://mrds72.com\n永久地址: https://mrds.com\n备用网址: https://mrdsx5.com\n备用线路1: big.ktgchwz.xyz\n备用线路2: adjust.ktgchwz.xyz\n备用线路3: borrow.ktgchwz.xyz\n备用线路4: black.ktgchwz.xyz\n获取地址: mrds.club@gmail.com",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://img2.baidu.com/it/u=2497591018,1494490685&fm=253&fmt=auto&app=138&f=JPEG?w=375&h=500",
    "sourceName": "每日大赛",
    "sourceUrl": "https://d3fzqoxno61m61.rnxuiofe.com/",
    "style": "iframe{\n\theight:600px\n}\ntitle{\n\tdisplay:block\n}"
  },
  {
    "articleStyle": 0,
    "customOrder": 4,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\":\"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36 Reader\"}",
    "jsLib": "function sleep(time) {\n    let endTime = new Date().getTime() + time\n    while(true){\n        if (new Date().getTime() > endTime){\n            return;\n        }\n    }\n}\n\nfunction sleepToast(text, second) {\n    let {java} = this\n    java.log(text)\n    java.longToast(text)\n    if (second === undefined) {second = 0.01}\n    sleep(1000*second)\n}\n\nlet bookSourceCommentText = `Pixiv 小说\n\n书源版本：无法获取\n使用说明：📌阅读版本 3.25.0527 及之后版本可用\n可用功能：✅搜索✅发现✅添加网址✅订阅源\n搜索小说：✅单篇✅系列✅标签✅作者\n发现小说：✅关注✅追更✅推荐✅发现\n发现小说：✅收藏✅书签✅首页✅排行\n添加网址：✅Pixiv小说链接✅Pixiv系列链接\n订阅用法：点击订阅源打开小说/系列小说，【刷新】，点击【加入书架】按钮，添加到书架\n\n书源发布：https://t.me/PixivSource\n项目地址：https://github.com/DowneyRem/PixivSource\n使用教程：https://downeyrem.github.io/PixivSource/Pixiv\n\n规则订阅：import 订阅源\nhttps://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/import.json\nhttps://raw.githubusercontent.com/DowneyRem/PixivSource/main/import.json\n\n⚙️ 书源设置：\n设置1️⃣：打开小说 - 菜单 - 登录 - 点击下方按钮\n设置2️⃣：编辑书源 - 基本 - 变量说明 - 修改并保存\n\n🚫 屏蔽作者(本地)：\n设置方法1️⃣：打开小说 - 菜单 - 登录 - 🚫 屏蔽作者\n`.trim()\n\nfunction updateSource() {\n    const {java, source} = this\n    let onlineSource, comment\n    java.longToast(\"🆙 更新书源\\n\\nJsdelivr CDN 更新有延迟\\nGithub 更新需代理\")\n    try {\n        let updateUrl = \"https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/pixiv.json\"\n        onlineSource = JSON.parse(java.get(updateUrl,{'User-Agent': 'Mozilla/5.0 (Linux; Android 14)','X-Requested-With': 'XMLHttpRequest'}).body())[0]  // 第1个书源\n        comment = onlineSource.bookSourceComment.split(\"\\n\")\n    } catch (e) {\n        try {\n            let updateUrl = \"https://raw.githubusercontent.com/DowneyRem/PixivSource/main/pixiv.json\"\n            onlineSource = JSON.parse(java.get(updateUrl,{'User-Agent': 'Mozilla/5.0 (Linux; Android 14)','X-Requested-With': 'XMLHttpRequest'}).body())[0]  // 第1个书源\n            comment = onlineSource.bookSourceComment.split(\"\\n\")\n        } catch (e) {\n            onlineSource = {lastUpdateTime: new Date().getTime(), bookSourceComment: bookSourceCommentText}\n            comment = onlineSource.bookSourceComment.split(\"\\n\")\n        }\n    }\n\n    let htm = `data:text/html; charset=utf-8,\n<html>\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>更新 Pixiv 书源</title>\n    <style> \n    table { text-align: center; margin: 0 auto; } .ann { display: flex; justify-content: center; align-items: center; height: 5vh; } \n    button { background-color: rgb(76, 175, 80); color: white; border: none; border-radius: 4px; height: 6vh; width: 30vw; overflow: hidden; } \n    button span { cursor: pointer; display: inline-block; position: relative; transition: 0.4s; } \n    button span:after { content: '>'; position: absolute; opacity: 0; top: 0; right: 30px; transition: 0.2s; } \n    button:active span { padding-right: 20px; } \n    button:active span:after { opacity: 1; right: -40px; }\n    </style>\n</head>\n\n<body>\n    <table border=\"1\" cellspacing=\"0\">\n        <th colspan=\"2\"> Pixiv 书源 \n        <a href=\"https://downeyrem.github.io/PixivSource/Pixiv\">🔰 使用指南</a>\n        || <a href=\"https://downeyrem.github.io/PixivSource/Sponsor\">❤️ 赞助开发</a>\n        </th>\n        <tr>\n            <td>☁️ 远程版本：${onlineSource.bookSourceComment.split(\"\\n\")[2].replace(\"书源版本：\", \"\")}</td>\n            <td>📆 更新：${java.timeFormat(onlineSource.lastUpdateTime)}</td>\n        </tr>\n        <tr><td colspan=\"2\" style=\"text-align: left;\">${comment.slice(3, 10).join(\"<br>\")}</td></tr>\n        <tr><td colspan=\"2\" style=\"text-align: left;\">${comment.slice(comment.length-20, comment.length).join(\"<br>\")}</td></tr>\n    </table>\n    \n    <table border=\"0\" cellspacing=\"20\">\n        <th colspan=\"2\"> 更新 Pixiv 书源 </th>\n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/pixiv.json\">\n            <button><span>更新书源<br>(Jsdelivr CDN)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/btsrk.json\">\n            <button><span>更新订阅<br>(Jsdelivr CDN)</span></button>\n            </a></div></td>\n        </tr>\n        \n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://raw.githubusercontent.com/DowneyRem/PixivSource/main/pixiv.json\">\n            <button><span>书源链接<br>(GitHub)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://raw.githubusercontent.com/DowneyRem/PixivSource/main/btsrk.json\">\n            <button><span>订阅链接<br>(GitHub)</span></button>\n            </a></div></td>\n        </tr>\n        \n        <tr><td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://codeberg.org/DowneyRem/PixivSource/raw/branch/main/pixiv.json\">\n            <button><span>备用书源链接<br>(Codeberg)</span></button>\n            </a></div></td>\n            \n            <td><div class=\"ann\">\n            <a href=\"legado://import/importonline?src=https://codeberg.org/DowneyRem/PixivSource/raw/branch/main/btsrk.json\">\n            <button><span>备用订阅链接<br>(Codeberg)</span></button>\n            </a></div></td>\n        </tr>\n    </table>\n</body>\n</html>`;\n    java.startBrowser(htm,'更新书源');\n    return []\n}",
    "lastUpdateTime": 1763913600251,
    "loadWithBaseUrl": true,
    "loginUi": "[\n    {\n        \"name\": \"🆙 更新书源\",\n        \"type\": \"button\",\n        \"action\": \"updateSource()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDD30 使用指南\",\n        \"type\": \"button\",\n        \"action\": \"startGithubReadme()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83D\\uDC1E 反馈问题\",\n        \"type\": \"button\",\n        \"action\": \"startGithubIssue()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"⭐️ 收藏项目\",\n        \"type\": \"button\",\n        \"action\": \"startGithubLogin()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"\\uD83C\\uDD7F️ 书源频道\",\n        \"type\": \"button\",\n        \"action\": \"startTelegram()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    },\n    {\n        \"name\": \"❤\\uFE0F 赞助开发\",\n        \"type\": \"button\",\n        \"action\": \"startGithubSponsor()\",\n        \"style\": {\n            \"layout_flexGrow\": 1,\n            \"layout_flexBasisPercent\": -1\n        }\n    }\n]",
    "loginUrl": "function getWebViewUA() {\n    let userAgent = String(java.getWebViewUA())\n    if (userAgent.includes(\"Windows NT 10.0; Win64; x64\")) {\n        userAgent = \"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36\"\n    }\n    return String(userAgent)\n}\n\nfunction login() {}\n\nfunction startBrowser(url, title) {\n    let msg = \"\", headers = `{\"headers\": {\"User-Agent\":\"${getWebViewUA()}\"}}`\n    if (url.includes(\"https://github.com\")) {\n        if (url.includes(\"issues\")) msg += \"🐞 反馈问题\"\n        else if (url.includes(\"doc\")) msg += \"🔰 使用指南\"\n        else msg += \"⭐️ 收藏项目\"\n        msg += \"\\n\\n即将打开 Github\\n请确认已开启代理/梯子/VPN等\"\n    } else if (url.includes(\"https://t.me\")) {\n        if (url.includes(\"FurryReading\")) msg += \"🐺 兽人阅读频道\"\n        else if (url.includes(\"joinchat\")) msg += \"🐞 反馈群组\"\n        msg += \"\\n\\n即将打开 Telegram\\n请确认已开启代理/梯子/VPN等\"\n    }\n    sleepToast(msg)\n    java.startBrowser(`${url}, ${headers}`, title)\n}\n\nfunction startGithub() {\n    startBrowser(\"https://github.com/DowneyRem/PixivSource\", \"书源介绍\")\n}\nfunction startGithubLogin() {\n    startBrowser(\"https://github.com/login?return_to=https://github.com/DowneyRem/PixivSource\", \"收藏项目\")\n}\nfunction startGithubIssue() {\n    startBrowser(\"https://github.com/DowneyRem/PixivSource/issues\", \"反馈问题\")\n}\nfunction startGithubReadme() {\n    startBrowser(\"https://downeyrem.github.io/PixivSource/Pixiv\", \"使用指南\")\n}\nfunction startGithubSponsor() {\n    startBrowser(\"https://downeyrem.github.io/PixivSource/Sponsor\", \"使用指南\")\n}\nfunction startTelegram() {\n    startBrowser(\"https://t.me/PixivSource\", \"Pixiv 书源频道\")\n}",
    "singleUrl": true,
    "sourceComment": "Pixiv 书源项目\n\n可用功能：✅导入书源✅更新书源\n\n书源发布：\nPixiv 书源频道 https://t.me/PixivSource\n兽人阅读频道 https://t.me/FurryReading\n\n项目地址：\nhttps://github.com/DowneyRem/PixivSource\nhttps://github.com/eigeen/PixivSourceProject\n\n规则订阅：Import 订阅源\nhttps://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/import.json\nhttps://raw.githubusercontent.com/DowneyRem/PixivSource/main/import.json",
    "sourceGroup": "7备份",
    "sourceIcon": "https://cdn.jsdelivr.net/gh/DowneyRem/PixivSource@main/doc/pic/BookSourcePixiv.png",
    "sourceName": "Pixiv 书源 发布页",
    "sourceUrl": "https://downeyrem.github.io/PixivSource"
  },
  {
    "articleStyle": 0,
    "customOrder": 5,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "1.3",
    "sourceUrl": "https://www.33ccpp.com/"
  },
  {
    "articleStyle": 3,
    "customOrder": 416,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\"User-Agent\": \"Mozilla/5.0 (Linux; Android 9) Mobile Safari/537.36\",\"referer\": \"{{baseUrl}}\"\n\t}",
    "jsLib": "let search = \"https://dns.jingluo.love/2025/68a878e00d302.jpg\";",
    "lastUpdateTime": 1775586135304,
    "loadWithBaseUrl": true,
    "ruleArticles": ".pornkvideos",
    "ruleContent": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<title>内容提取</title>\n<!-- v2025.05.10 -->\n\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.css\" />\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.js\"></script>\n<style>\n    body { font-family: Arial, sans-serif; font-size: 16px; }\n    #title, #page, #loading-status { margin: 0 auto; font-size: 20px; text-align: center; }\n    #description, #urls, #video-url, #video-sources, #messages { width: 100%; max-width: 800px; margin: 1.5px auto; font-size: 14px; text-align: left; word-wrap: break-word; white-space: pre-wrap; }\n    #text, #text :not(img), #text img + * { text-indent: 2em; width: 100%; font-size: 16px; line-height: 1.5em; margin-top: 0; margin-bottom: 0; word-wrap: break-word; white-space: pre-wrap; }\n    img, #text img { width: 100%; height: auto; display: block; margin-bottom: 1.5px; }\n    .flex-container { display: flex; justify-content: center; align-items: center; gap: 10px; margin: 1.5px 0; font-size: 14px; }\n    button, select { flex: 1 1 31%; padding: 3px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; cursor: pointer; background-color: #f9f9f9; transition: background-color 0.3s ease; margin: 1.5px; min-width: 0; font-size: 14px; }\n    #url-select, #video-source-select { flex: 1 1 100%; margin-left: 0; margin-right: 0; text-align: center; }\n    #video-element { width: 100%; height: auto; }\n    textarea { width: 100%; height: auto; min-height: 100px; box-sizing: border-box; resize: vertical; }\n    .error, .warn { color: red; }\n</style>\n</head>\n<body>\n    <h3 id=\"title\">{{@@title@text||h1.0@text||h2.0@text||.title.0@text}}</h3>\n    <p id=\"description\">{{@@.info.0@html||.jianjie@html}}</p>\n    <p id=\"page\" style=\"display:none;\">共<span id=\"total-pages\">1</span>页</p>\n    <p id=\"loading-status\" style=\"display:none;\"></p>\n\n    <div class=\"flex-container\" id=\"loading-buttons\" style=\"display:none;\">\n        <button id=\"prev-page-btn\">上一页</button>\n        <button id=\"next-page-btn\">下一页</button>\n        <button id=\"auto-load-btn\">自&nbsp;&nbsp;动</button>\n    </div>\n    \n    <div class=\"flex-container\">\n        <select id=\"url-select\" style=\"display:none;\"></select>\n    </div>\n    \n    <div class=\"flex-container\">\n        <button id=\"toggle-urls-btn\">显/隐网址</button>\n        <button id=\"toggle-messages-btn\">显/隐信息</button>\n        <button id=\"toggle-debug-btn\">显/隐调试</button>\n    </div>\n    <div id=\"urls\"></div>\n    <div id=\"messages\"></div>\n    <div id=\"debug-info\"></div>\n    <div id=\"video-url\"></div>\n    <div id=\"video-container\" style=\"display: none;\">\n        <video id=\"video-element\" controls preload=\"auto\" width=\"640\" height=\"264\">\n            <source id=\"video-source\" src=\"\" type=\"\">您的浏览器不支持 video 标签。\n        </video>\n    </div>\n    <div class=\"flex-container\" id=\"video-source-container\" style=\"display: none;\">\n        <select id=\"video-source-select\" onchange=\"updateVideoSource()\"></select>\n    </div>\n    <div id=\"images\"></div>\n    <div id=\"text\"></div>\n\n    <script>\n        // 配置对象，包含各种选择器、延迟时间等配置项\n        const config = {    \n            videoSelector: 'body', // 视频选择器\n            imgSelector: '.gridlane-box-inside img,.photos figure img,.content p img', // 图片选择器\n            textSelector: '#content', // 文本选择器\n            debugSelector: '#content, .page, .pager, .content, script', // 调试信息选择器\n            swapImageAttributes: false, // 是否交换图片属性\n            delayTime: 1500, // 延迟提取时间\n            retryDelayTime: 1500, // 重试加载延迟时间\n            maxLoadAttempts: 3, // 最大加载次数\n            autoLoading: false, // true自动模式，false单页模式\n            debugOnce: 0, // 只在特定索引输出一次调试信息\n            totalPagesText: '{{@@.page.0@a.-2@textNodes}}', // 总页码\n            urlSuffixToRemove: /\\.html$/, // 移除url后缀\n            pageUrlText: '{urlPrefix}_{i}.html', // 拼接URL模板        \n            ListMode: true, // true网址列表模式，false网址拼接模式    \n            initialUrls: `{{@@#sort-item-5.0@a@href}}`, // 网址\n            initialUrlsName: `{{@@#sort-item-5.0@a@span@text}}`, // 网址名称\n            sourceurl: '', // 来源URL前缀\n        };\n\n        let videoSources = []; // 存储视频源数组\n        let loadAttempts = {}; // 记录每个URL的加载尝试次数\n        let urls = []; // 存储所有页面的URL\n        let imageBox;\n        let textBox;\n        let currentPageIndex = 0; // 当前页面索引\n        let canLoadNextPage = true; // 控制是否可以加载下一页\n        let autoLoadInProgress = false; // 自动加载状态\n\n        // 构建URL列表\n        function buildUrls(totalPages, baseUrl) {\n            let initialUrlsArray = config.initialUrls.trim().split('\\n').filter(url => url.trim() !== '');\n            let initialUrlsNameArray = config.initialUrlsName.trim().split('\\n').filter(name => name.trim() !== '');\n\n            if (config.ListMode && initialUrlsArray.length > 0) {\n                if (initialUrlsArray.length !== initialUrlsNameArray.length) {\n                    $('#messages').append(`<span class=\"warn\">警告：initialUrls 和 initialUrlsName 的长度不匹配。</span><br>`);\n                }\n\n                urls = initialUrlsArray.map(url => {\n                    if (config.sourceurl && url.startsWith('/') && !/^https?:\\/\\//i.test(url)) {\n                        return config.sourceurl.replace(/\\/$/, '') + url;\n                    } else {\n                        return url;\n                    }\n                });\n\n                urls.forEach((url, index) => {\n                    const name = initialUrlsNameArray[index] || `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            } else {\n                if (totalPages === 1) {\n                    urls.push(baseUrl);\n                } else {\n                    urls.push(baseUrl);\n                    for (let i = 2; i <= totalPages; i++) {\n                        urls.push(config.pageUrlText.replace('{urlPrefix}', baseUrl.replace(config.urlSuffixToRemove, '').replace(/\\/$/, '')).replace('{i}', i));\n                    }\n                }\n\n                urls.forEach((url, index) => {\n                    const name = `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            }\n\n            $('#total-pages').text(urls.length);\n            toggleNavigationButtons();\n            toggleTotalPagesDisplay();\n        }\n\n        // 规范化URL\n        function normalizeUrl(url) {\n            if (typeof url !== 'string' || !url.trim()) {\n                return '';\n            }\n            const match = url.match(/['\"](.*?)['\"]/);\n            if (match && match[1]) {\n                url = match[1];\n            }\n\n            function processUrl(str) {\n                str = str.trim();\n                str = str.replace(/\\\\u[\\dA-F]{4}/gi, match => String.fromCharCode(parseInt(match.replace(/\\\\u/g, ''), 16)));\n                str = decodeURIComponent(str);\n                str = str.replace(/^http:\\/([^/])/, 'http://$1');\n                str = str.replace(/^https:\\/([^/])/, 'https://$1');\n                return str;\n            }\n            return processUrl(url);\n        }\n\n        // 清空容器内容\n        function clearContainers() {\n            $('#messages').empty();\n            $('#images').empty();\n            $('#text').empty();\n        }\n\n        // 更新图像源\n        function updateImageSrc(elements, shouldSwap) {\n            elements.each(function () {\n                const $this = $(this);\n                const attrsToUpdate = {};\n                if (shouldSwap) {\n                    ['data-original', 'data-src', 'data-url'].forEach(attr => {\n                        if ($this.attr(attr)) {\n                            attrsToUpdate['src'] = $this.attr(attr);\n                        }\n                    });\n                }\n                $this.attr(attrsToUpdate);\n            });\n            return elements;\n        }\n\n        // 切换导航按钮显示状态\n        function toggleNavigationButtons() {\n            if ($('#url-select option').length > 1 && !config.autoLoading) {\n                $('#loading-buttons').show();\n                $('#url-select').show();\n            } else {\n                $('#loading-buttons').hide();\n                $('#url-select').hide();\n            }\n        }\n\n        // 显示加载状态\n        function showLoadingStatus(pageNumber) {\n            const selectedOption = $('#url-select option:selected').text();\n            $('#loading-status').text(`正在加载：${selectedOption}`).show();\n        }\n\n        // 隐藏加载状态\n        function hideLoadingStatus() {\n            $('#loading-status').hide();\n        }\n\n        // 加载指定索引的内容\n        function loadContent(index) {\n            if (index < 0 || index >= urls.length || !canLoadNextPage) return;\n            canLoadNextPage = false;\n            currentPageIndex = index;\n            $('#url-select').val(index);\n            $('#messages').append(`<div>当前地址: <span class=\"warn\">${urls[index]}</span></div>`);\n            if (autoLoadInProgress) {\n                showLoadingStatus(index + 1);\n            }\n            $.ajax({\n                url: urls[index],\n                type: 'GET',\n                success: function (data) {\n                    try {\n                    const $data = $(data);\n                    let updatedHtmlContent = data.replace(/(['\"])(\\/\\/)(?!\\/)/g, '$1https://')\n                        .replace(/src=\"upload/gi, 'src=\"/upload')\n                        .replace(/style=[\"'][^'\"]+[\"']/gi, '')\n                        .replace(/\\\\\\//g, '/');\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(updatedHtmlContent, \"text/html\");\n\n                    if (config.debugOnce === index) {\n                        const debugElements = $(doc).find(config.debugSelector);\n                        if (debugElements.length > 0) {\n                            const debugContents = $('<pre>').html(debugElements.clone().wrapAll('<div/>').parent().html()).html();\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">${debugContents}</textarea></span>`);\n                        } else {\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">调试信息未提取到内容，请检查选择器！</textarea></span>`);\n                        }\n                    }\n                    // 方法1：提取视频\n                    const videoSources1 = [];\n                    const videoContents = $(doc).find(config.videoSelector);\n                    const videoTags = $(videoContents).find('video, source');\n                    videoTags.each(function() {\n                        const videosrc = $(this).attr('src') || \n                                     $(this).attr('data-src') || \n                                     $(this).attr('data-original') || '';\n                        \n                        if (videosrc) {\n                            videoSources1.push(videosrc);\n                        }\n                    });\n                    //反馈\n                    if (videoSources1.length > 0) {\n                        $('#messages').append(`<span>方法1，找到 ${videoSources1.length} 个视频。</span><br>`);\n                    }\n\n                    // 方法2：正则提取视频\n                    const regex = /['\"]https?[^'<>\"]+(m3u8|mp4|webm|ogg|flv|mp3|m4a|wav|ape|flac)([^'<>\"]+)?['\"]/gi;\n                    const matches = data.match(regex);\n                    const videoSources2 = [];\n\n                    if (matches) {\n                        const uniqueMatches = [...new Set(matches)];\n                    \n                        uniqueMatches.forEach(match => {\n                            const normalizedSrc = normalizeUrl(match.replace(/['\"]/g, ''));\n                            videoSources2.push(normalizedSrc);\n                        });\n                    }\n                    //反馈\n                    if (videoSources2.length > 0) {\n                        $('#messages').append(`<span>方法2，找到 ${videoSources2.length} 个视频。</span><br>`);\n                    }\n\n                    // 合并两种方法的结果\n                    videoSources = [...videoSources1, ...videoSources2];\n\n                    // 去重并标准化 URL\n                    const imageExtensions = /\\.(jpg|jpeg|png|gif|bmp|svg)$/i;\n\n                    videoSources = videoSources\n                                  .map(src => normalizeUrl(src.replace(/\\\\+/g, '')))\n                                  .filter(src => src) // 过滤空值\n                                  .filter(src => !imageExtensions.test(src)); // 移除图片地址\n                        \n                    videoSources = [...new Set(videoSources)];// 去重\n\n                    // 显示最终结果\n                    $('#messages').append(`<span>总共找到 ${videoSources.length} 个视频。</span><br>`);\n\n                    if (videoSources.length > 0) {\n                        $('#messages').append(`<span>成功提取到视频，找到 ${videoSources.length} 个视频。</span><br>`);\n                        videoSources.forEach((src, idx) => {\n                            $('#messages').append(`<div>视频地址:<span class=\"warn\"> ${src}</span><br></div>`);\n                            $('#video-source-select').append(`<option value=\"${idx}\">视频源 ${idx + 1}</option>`);\n                        });\n                    \n                        if (videoSources.length == 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').hide();\n                            updateVideoSource();\n                        } else if (videoSources.length > 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').show();\n                            updateVideoSource();\n                        } else {\n                            $('#video-container').hide();\n                            $('#video-url').hide();\n                            $('#video-source-container').hide();\n                        }\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未找到视频源。</span><br>`);\n                        $('#video-container').hide();\n                        $('#video-url').hide();\n                        $('#video-source-container').hide();\n                    }\n\n                    //提取图片\n                    const $imgContents = $(doc).find(config.imgSelector);\n                    const shouldSwap = config.swapImageAttributes;\n                    const newContents = updateImageSrc($imgContents.clone(), shouldSwap);\n                    $('#images').append(newContents).show();\n                    if (newContents.length > 0) {\n                        $('#messages').append(`<span>成功提取图片，共 ${newContents.length} 张。</span><br>`);\n                        newContents.each(function () {\n                            const imgSrc = $(this).attr('src') || $(this).attr('data-original') || $(this).attr('data-src') || $(this).attr('data-url');\n                            $('#messages').append(`<div>地址:<span class=\"warn\"> ${imgSrc}</span><br></div>`);\n                        });\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图片。</span><br>`);\n                    }\n\n                    //提取图片和文本\n                    const textContents = $(doc).find(config.textSelector).map(function () {\n                        const $currentContents = $(this);\n                        $currentContents.find('img + br, script, video, source, iframe').remove();\n                        $currentContents.html($currentContents.html().replace(/>\\s+/gi, '>').replace(/<\\/?br\\s*([^>]*)\\s*\\/?>/gi, '\\n').replace(/\\n+/g, '\\n'));\n                        return $currentContents.html();\n                    }).get().join('');\n                    if (textContents.trim()) {\n                        $('#text').append(`<span>${textContents}</span><br>`).show();\n                        $('#messages').append(`<span>成功提取图文。</span><br>`);\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图文。</span><br>`);\n                    }\n\n                    if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                        setTimeout(() => { \n                            canLoadNextPage = true;\n                            loadContent(currentPageIndex + 1); \n                        }, config.delayTime);\n                    } else {\n                        canLoadNextPage = true;\n                        if (autoLoadInProgress) {\n                            hideLoadingStatus();\n                        }\n                    }\n                } catch (parseError) {\n                    $('#messages').append(`<span class=\"error\">解析页面内容时发生错误: ${parseError.message}</span><br>`);\n                    handleLoadFailure(urls, index);\n                } finally {\n                    if (imageBox) imageBox.viewer.update();\n                    if (textBox) textBox.viewer.update();\n                }\n            },\n            error: function (jqXHR, textStatus, errorThrown) {\n                let errorMessage = `内容加载失败: ${urls[index]}`;\n                switch (textStatus) {\n                    case 'timeout':\n                        errorMessage += ', 请求超时';\n                        break;\n                    case 'abort':\n                        errorMessage += ', 请求被取消';\n                        break;\n                    case 'parsererror':\n                        errorMessage += ', 解析响应出错';\n                        break;\n                    default:\n                        errorMessage += `, 状态码: ${jqXHR.status}, 错误信息: ${errorThrown}`;\n                        break;\n                }\n                $('#messages').append(`<span class=\"error\">${errorMessage}</span><br>`);\n                handleLoadFailure(urls, index);\n                }\n            });\n        }\n\n        // 处理加载失败的情况\n        function handleLoadFailure(urls, index) {\n            if (!loadAttempts[urls[index]]) {\n                loadAttempts[urls[index]] = 1;\n            } else {\n                loadAttempts[urls[index]]++;\n            }\n            if (loadAttempts[urls[index]] <= config.maxLoadAttempts) {\n                const retryMessage = `第${index + 1}页加载失败，正在进行第${loadAttempts[urls[index]]}次加载！`;\n                $('#messages').append(`<span class=\"error\">${retryMessage}</span><br>`);\n                setTimeout(() => { \n                    canLoadNextPage = true;\n                    loadContent(index); \n                }, config.retryDelayTime);\n            } else {\n                const finalErrorMessage = `第${index + 1}页加载失败，已达到最大尝试次数(${config.maxLoadAttempts})！`;\n                $('#messages').append(`<span class=\"error\">${finalErrorMessage}</span><br>`);\n                if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                    setTimeout(() => { \n                        canLoadNextPage = true;\n                        loadContent(currentPageIndex + 1); \n                    }, config.delayTime);\n                } else {\n                    canLoadNextPage = true;\n                    if (autoLoadInProgress) {\n                        hideLoadingStatus();\n                    }\n                }\n            }\n        }\n\n        // 更新视频源\n        function updateVideoSource() {\n            const selectedIndex = parseInt(document.getElementById('video-source-select').value);\n            if (isNaN(selectedIndex) || !videoSources[selectedIndex]) {\n                $('#messages').append(`<span class=\"warn\">未找到有效的视频源。</span><br>`);\n                console.warn(\"Invalid or undefined video source:\", selectedIndex, videoSources);\n                return;\n            }\n\n            const selectedSource = videoSources[selectedIndex];\n            document.getElementById('video-url').textContent = `视频地址:\\n ${selectedSource}`;\n\n            const videoSourceElement = document.getElementById('video-source');\n            videoSourceElement.src = selectedSource;\n\n            const videoElement = document.getElementById('video-element');\n            videoElement.load();\n\n            $('#messages').append(`<span>更新视频源为: ${selectedSource}</span><br>`);\n            console.log(\"Updated video source to:\", selectedSource);\n        }\n\n        // 切换总页数显示状态\n        function toggleTotalPagesDisplay() {\n            if (urls.length > 1) {\n                $('#page').show();\n            } else {\n                $('#page').hide();\n            }\n        }\n\n        // 页面加载完成后执行的主要逻辑\n        $(document).ready(function () {\n            imageBox = document.getElementById('images');\n            textBox = document.getElementById('text');\n            if (imageBox && textBox) {\n                new Viewer(imageBox, { title: true, interval: 2000 });\n                new Viewer(textBox, { title: true, interval: 2000 });\n            }\n\n            const totalPagesText = config.totalPagesText;\n            const totalPages = parseInt(totalPagesText, 10) || 1;\n            const baseUrl = '{{baseUrl}}';\n\n            clearContainers();\n            $('#urls, #debug-info textarea, #video-url, #video-source-select').empty();\n            $('#urls, #messages, #debug-info, #video-url, #video-container, #video-source-container, #images, #text').hide();\n\n            buildUrls(totalPages, baseUrl);\n\n            const urlSelect = document.getElementById('url-select');\n            if (urlSelect.options.length > 0) {\n                urlSelect.value = '0'; \n\n                if (config.autoLoading) {\n                    autoLoadInProgress = true;\n                    for (let i = 0; i < urls.length; i++) {\n                        loadContent(i);\n                    }\n                } else {\n                    loadContent(0);\n                }\n            } else {\n                loadContent(0);\n            }\n\n            $('#url-select').change(function () {\n                clearContainers();\n                const selectedIndex = parseInt($(this).val());\n                loadContent(selectedIndex);\n            });\n            $('#prev-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex > 0) {\n                    loadContent(currentPageIndex - 1);\n                }\n            });\n            $('#next-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex < urls.length - 1) {\n                    loadContent(currentPageIndex + 1);\n                }\n            });\n            $('#auto-load-btn').click(function () {\n                autoLoadInProgress = true;\n                showLoadingStatus(1); \n                for (let i = currentPageIndex + 1; i < urls.length; i++) {\n                    loadContent(i);\n                }\n            });\n            $('#toggle-messages-btn').click(function () { $('#messages').toggle(); });\n            $('#toggle-urls-btn').click(function () { $('#urls').toggle(); });\n            $('#toggle-debug-btn').click(function () { $('#debug-info').toggle(); });\n        });\n    </script>\n</body>\n</html>",
    "ruleImage": "img@data-src",
    "ruleLink": "/vodplay/{{@a.0@href##voddetail/(.*).html##$1##}}-1-1.html",
    "ruleNextPage": "text.下页@href",
    "rulePubDate": ".vlength@text",
    "ruleTitle": "a@text",
    "singleUrl": false,
    "sortUrl": "国产色情::/vodtype/12.html\n日本无码::/vodtype/20.html\n自拍偷拍::/vodtype/21.html\n人妻熟女::/vodtype/22.html\n黑人洋屌::/vodtype/23.html\n欧美精品::/vodtype/24.html\n岛国女优::/vodtype/25.html\n萝莉少女::/vodtype/26.html\n国产精品::/vodtype/55.html\n国产直播::/vodtype/56.html\n动漫禁漫::/vodtype/57.html\n黑料吃瓜::/vodtype/58.html\n欧美大屌::/vodtype/60.html\n探花约炮::/vodtype/61.html\n华语精品::/vodtype/63.html\n乱伦精品::/vodtype/64.html\n学生合集::/vodtype/65.html\n卡通动漫::/vodtype/69.html\n乱伦中出::/vodtype/70.html\n传媒原创::/vodtype/71.html\n口爆颜射::/vodtype/72.html\n岛国群交::/vodtype/73.html\n日本有码::/vodtype/74.html\n中文字幕::/vodtype/75.html\n吃瓜爆料::/vodtype/76.html\n角色扮演::/vodtype/77.html\n淫娃自慰::/vodtype/78.html\n日本有码::/vodtype/80.html\n主播网红::/vodtype/81.html\n韩国直播::/vodtype/84.html\n公开漏出::/vodtype/85.html\n日本无码::/vodtype/86.html\n重口调教::/vodtype/88.html\n户外打野::/vodtype/89.html",
    "sourceComment": "shewo1.cc",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://baf7baf7.shewo11.cc/template/shewo/images/logo.png",
    "sourceName": "射我里面了",
    "sourceUrl": "https://baf7baf7.shewo11.cc/"
  },
  {
    "articleStyle": 2,
    "customOrder": 420,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n  \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\",\n  \"Referer\": \"https://meirentu.club/\"\n}",
    "lastUpdateTime": 1769069467887,
    "loadWithBaseUrl": true,
    "ruleArticles": "li.i_list",
    "ruleContent": "<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n<title>{{@@h1@text}}</title>\n<style>\nbody {\n    margin: 0;\n    background: #000;\n    color: #eee;\n    font-family: sans-serif;\n}\n\n#statusBar {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    z-index: 999;\n    background: rgba(0, 0, 0, 0.7);\n    color: #aaa;\n    padding: 4px 10px;\n    font-size: 12px;\n    text-align: center;\n    backdrop-filter: blur(2px);\n    pointer-events: none;\n}\n\n#imgList img {\n    display: block;\n    width: 100%;\n    height: auto;\n    margin: 0;\n}\n</style>\n</head>\n<body>\n\n<div id=\"statusBar\">加载中…</div>\n\n\n{{@@h1@all}}\n\n<div id=\"detail\">\n{{@@article@all}}\n{{@@class.item_info@all}}\n</div>\n\n\n<div id=\"imgList\"></div>\n\n<script>\n// === 配置 ===\nconst pageUrls = `{{@@class.page@a:not(.current)@href}}`\n  .split('\\n')\n  .map(s => s.trim())\n  .filter(Boolean);\n\nlet allImages = []; // 所有已加载的图片URL\nlet pageImageCounts = []; // 每页图片数量，用于定位页码\nlet isLoading = false;\nlet currentPageIndex = 0; // 当前正在加载的页面索引\nconst maxRetry = 2;\nconst loadDelay = 100; // 页面组间的加载延迟（毫秒）\nconst batchSize = 5; // 每次加载的页面数量\n\n// === DOM ===\nconst imgList = document.getElementById('imgList');\nconst statusBar = document.getElementById('statusBar');\n\n// === 工具函数 ===\nfunction showStatus(text) {\n    if (statusBar) statusBar.textContent = text;\n}\n\n// 获取某页图片（简化版，优先 iframe）\nasync function fetchPageImages(url) {\n    return new Promise((resolve, reject) => {\n        const iframe = document.createElement('iframe');\n        iframe.style.display = 'none';\n        const timeout = setTimeout(() => {\n            cleanup();\n            reject(new Error('超时'));\n        }, 5000); // 缩短超时时间\n        \n        function cleanup() {\n            clearTimeout(timeout);\n            if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n        }\n        \n        iframe.onload = () => {\n            try {\n                const doc = iframe.contentDocument;\n                let imgs = doc.querySelectorAll('.content_left img') ||\n                           doc.querySelectorAll('.content img') ||\n                           doc.querySelectorAll('img');\n                const urls = Array.from(imgs).map(i => i.src).filter(Boolean);\n                cleanup();\n                resolve(urls);\n            } catch (e) {\n                cleanup();\n                reject(e);\n            }\n        };\n        iframe.onerror = () => { cleanup(); reject(new Error('加载失败')); };\n        iframe.src = url;\n        document.body.appendChild(iframe);\n    });\n}\n\n// 追加一页图片\nfunction appendPage(images) {\n    images.forEach(src => {\n        const img = document.createElement('img');\n        img.src = src;\n        img.loading = 'lazy';\n        imgList.appendChild(img);\n    });\n    allImages.push(...images);\n    pageImageCounts.push(images.length);\n}\n\n// 计算当前可视区域的图片索引\nfunction getCurrentImageIndex() {\n    const imgs = imgList.querySelectorAll('img');\n    if (imgs.length === 0) return -1;\n\n    // 优先选\"中心点最接近视口垂直中心\"的图片\n    let bestIndex = 0;\n    let minDistance = Infinity;\n\n    for (let i = 0; i < imgs.length; i++) {\n        const rect = imgs[i].getBoundingClientRect();\n        const centerY = rect.top + rect.height / 2;\n        const viewportCenter = window.innerHeight / 2;\n        const distance = Math.abs(centerY - viewportCenter);\n\n        // 如果图片完全不可见，跳过（可选）\n        if (rect.bottom < 0 || rect.top > window.innerHeight) {\n            continue;\n        }\n\n        if (distance < minDistance) {\n            minDistance = distance;\n            bestIndex = i;\n        }\n    }\n\n    return bestIndex;\n}\n\n// 根据图片索引计算所在页码\nfunction getPageInfo(imageIndex) {\n    if (imageIndex < 0) return { pageNum: 0, imageInPage: 0 };\n    let count = 0;\n    for (let i = 0; i < pageImageCounts.length; i++) {\n        if (imageIndex < count + pageImageCounts[i]) {\n            return {\n                pageNum: i + 1,\n                imageInPage: imageIndex - count + 1\n            };\n        }\n        count += pageImageCounts[i];\n    }\n    return { pageNum: pageImageCounts.length, imageInPage: pageImageCounts.at(-1) || 0 };\n}\n\n// 更新状态栏\nfunction updateStatusBar() {\n    const idx = getCurrentImageIndex();\n    if (idx === -1) return;\n    \n    const { pageNum, imageInPage } = getPageInfo(idx);\n    const totalPages = pageUrls.length;\n    const totalImages = allImages.length;\n    \n    showStatus(`[图片: ${idx + 1} / ${totalImages} | 页码: ${pageNum} / ${totalPages}]`);\n}\n\n// 批量加载多个页面\nasync function loadBatchPages(startIndex, count) {\n    const endIndex = Math.min(startIndex + count, pageUrls.length);\n    let successfulPages = 0;\n    \n    for (let i = startIndex; i < endIndex; i++) {\n        const pageIndex = i;\n        let retry = 0;\n        let success = false;\n        \n        // 重试机制\n        while (retry < maxRetry && !success) {\n            try {\n                showStatus(`正在加载 ${pageIndex + 1} / ${pageUrls.length} 页…`);\n                const urls = await fetchPageImages(pageUrls[pageIndex]);\n                if (urls.length === 0) {\n                    throw new Error('无图片');\n                }\n                appendPage(urls);\n                successfulPages++;\n                updateStatusBar(); // 每页加载后更新状态\n                success = true;\n            } catch (e) {\n                retry++;\n                if (retry >= maxRetry) {\n                    showStatus(`❌ 跳过第 ${pageIndex + 1} 页`);\n                    pageImageCounts.push(0); // 占位\n                    break;\n                }\n                await new Promise(r => setTimeout(r, 500)); // 重试延迟\n            }\n        }\n    }\n    \n    return successfulPages;\n}\n\n// 自动加载所有页面（分批）\nasync function loadAllRemainingPages() {\n    if (isLoading || currentPageIndex >= pageUrls.length) {\n        return;\n    }\n    \n    isLoading = true;\n    \n    try {\n        // 分批加载页面\n        while (currentPageIndex < pageUrls.length) {\n            const remainingPages = pageUrls.length - currentPageIndex;\n            const currentBatchSize = Math.min(batchSize, remainingPages);\n            \n            showStatus(`批量加载 ${currentPageIndex + 1}-${currentPageIndex + currentBatchSize} 页…`);\n            \n            // 加载当前批次\n            await loadBatchPages(currentPageIndex, currentBatchSize);\n            \n            currentPageIndex += currentBatchSize;\n            \n            // 如果不是最后一页，添加短暂延迟\n            if (currentPageIndex < pageUrls.length) {\n                await new Promise(r => setTimeout(r, loadDelay));\n            }\n        }\n        \n        showStatus(`✅ 全部页面加载完成，共 ${allImages.length} 张图片`);\n    } catch (error) {\n        showStatus('❌ 加载过程中出现错误');\n        console.error(error);\n    } finally {\n        isLoading = false;\n    }\n}\n\n// === 初始化 ===\n(async () => {\n    if (pageUrls.length === 0) {\n        showStatus('⚠️ 未获取到分页');\n        return;\n    }\n    \n    try {\n        showStatus(`开始加载，共 ${pageUrls.length} 页…`);\n        \n        // 立即加载第一页（不等待）\n        showStatus('加载第 1 页…');\n        const urls = await fetchPageImages(pageUrls[0]);\n        appendPage(urls);\n        currentPageIndex = 1; // 第一页已加载\n        \n        showStatus(`✅ 首页加载完成 (${urls.length}张图片)`);\n        updateStatusBar();\n        \n        // 启动滚动监听（仅更新状态栏）\n        window.addEventListener('scroll', updateStatusBar, { passive: true });\n        \n        // 立即开始加载剩余所有页面（分批）\n        loadAllRemainingPages();\n        \n    } catch (e) {\n        showStatus('❌ 首页加载失败');\n        console.error(e);\n    }\n})();\n</script>\n</body>\n</html>",
    "ruleImage": "img@data-src||img@src",
    "ruleLink": "a.0@href",
    "ruleNextPage": ".current+a@href||a[aria-label=\"Next\"]@href",
    "rulePubDate": "{{@@span.0@text}}  {{@@span.1@text}}",
    "ruleTitle": ".meta-title@text",
    "singleUrl": false,
    "sortUrl": "搜索::https://meirentu.club/s/{{source.getVariable()}}-1.html\n首页::/\n热门精选::/hots.html\nXiuRen秀人网::/group/XiuRen-1.html\nMFStar模范学院::/group/MFStar-1.html\nMiStar魅妍社::/group/MiStar-1.html\nMyGirl美媛馆::/group/MyGirl-1.html\nImiss爱蜜社::/group/Imiss-1.html\nBoLoli兔几盟::/group/BoLoli-1.html\nYouWu尤物馆::/group/YouWu-1.html\nUxing优星馆::/group/Uxing-1.html\nMiiTao蜜桃社::/group/MiiTao-1.html\nFeiLin嗲囡囡::/group/FeiLin-1.html\nWingS影私荟::/group/WingS-1.html\nTaste顽味生活::/group/Taste-1.html\nLeYuan星乐园::/group/LeYuan-1.html\nHuaYan花の颜::/group/HuaYan-1.html\nDKGirl御女郎::/group/DKGirl-1.html\nMintYe薄荷叶::/group/MintYe-1.html\nYouMi尤蜜荟::/group/YouMi-1.html\nCandy糖果画报::/group/Candy-1.html\nMTMeng模特联盟::/group/MTMeng-1.html\nMicat猫萌榜::/group/Micat-1.html\nHuaYang花漾::/group/HuaYang-1.html\nXingYan星颜社::/group/XingYan-1.html\nXiaoYu画语界::/group/XiaoYu-1.html",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://meirentu.club/static/img/logo.png",
    "sourceName": "美人图 - 秀人",
    "sourceUrl": "https://meirentu.club "
  },
  {
    "articleStyle": 2,
    "customOrder": 505,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "ul@li",
    "ruleContent": "   <h3>{{@@.h@tag.h1@text}}</h3>\r\n    <div id=\"box\">{{@@id.picg@tag.img@html}}</div>\r\n",
    "ruleImage": "img@src",
    "ruleLink": "a@href",
    "ruleNextPage": "page",
    "ruleTitle": "class.title@text",
    "singleUrl": false,
    "sortUrl": "摄影图库::http://www.sytuk.com/shey/yingtiiurm/11_1.html\n经典套图::http://www.jdtaotu.com/s.asp?keyword=%CD%F8%C2%B7\n女神美图::http://www.nsmeitu.com/s.asp?keyword=%CD%F8%C2%B7\n极品美女图::http://www.jpmnt.com/s.asp?keyword=%CD%F8%C2%B7\n高清网红图::http://www.gqwht.com/s.asp?keyword=%CD%F8%C2%B7\n漂亮网红图::http://www.plwht.com/s.asp?keyword=%CD%F8%C2%B7\n模特摄影图::http://www.mtsyt.com/s.asp?keyword=%CD%F8%C2%B7\n漂亮美图::http://www.plmeitu.com/s.asp?keyword=%CD%F8%C2%B7\n私房写真图::http://www.sfxzt.com/s.asp?keyword=%CD%F8%C2%B7\n极品女神图::http://www.jpnst.com/s.asp?keyword=%CD%F8%C2%B7\n国产写真图::http://www.gcxzt.com/s.asp?keyword=%CD%F8%C2%B7\n少女套图::http://www.sntaotu.com/s.asp?keyword=%CD%F8%C2%B7\n模特写真图::http://www.mtxzt.com/chis/wangluo/1.html",
    "sourceComment": "分类无法显示下一页",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "2.7",
    "sourceUrl": "http://www.mtxzt.com",
    "style": "/*标题相关*/\r\nh3{text-align:center}\r\nh6{margin-bottom:0}\r\nimg{width:100%}\nh5{margin-bottom:0;padding-left:5;}"
  },
  {
    "articleStyle": 0,
    "customOrder": 506,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": " {\n\"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36\",\"Cookie\":\"__cfduid=d150f32feeec7048d35993a8a642d2c0e1600348724; AVS=k29ctap8qhbuncoijpdkckr5v7\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "class.left@class.row@class.game-item&&class.left@class.row@class.video-item",
    "ruleContent": "@js:\nheader={\"Referer\":baseUrl};\nheaders={\"headers\":JSON.stringify(header)}\nif(baseUrl.match(/gif/)){\nvar doc = org.jsoup.Jsoup.parse(result);\nvar gif = String(doc).match(/gif.{5,10}.webm/);\nvar preview = 'https://www.hentaicloud.com/media/'+gif;\n\nif(String(doc).match(/From Video/)){\nvar url = doc.select(\"div.fromvideo\").select(\"a\").attr(\"href\");\nvar allUrl = 'https://www.hentaicloud.com'+url;\nvar doc = org.jsoup.Jsoup.connect(allUrl).get();\nvar spt = doc.select(\"source\").toString();\nvar src = spt.match(/https.{36}hd.{5,10}mp4/);\nresult = '<body><div><video controls=\"true\" width=\"100%\" autoplay=\"true\" src ='+preview+'></div><div><a href='+src+' >点击看全片</a></div></body>'\n}else{  \nresult = '<body><div><video controls=\"true\" width=\"100%\" autoplay=\"true\" src ='+preview+'></div><div><a>此片暂无出处</a></div></body>'\n}\n\n}else{\nvar doc = org.jsoup.Jsoup.parse(result);\nvar spt = doc.select(\"source\").toString();\nvar src = spt.match(/https.{36}hd.{5,10}mp4/);\nvar video='<iframe src='+src+' width=\"100%\" height=\"560\" frameborder=\"no\" allowfullscreen=\"true\">'  \nresult = video}",
    "ruleImage": "tag.img@src",
    "ruleLink": "tag.a@href",
    "ruleNextPage": "page",
    "rulePubDate": "@js:\nvar doc = org.jsoup.Jsoup.parse(result)\nvar text = doc.select(\"div.info\").select(\"span\").textNodes();\nif(text.size()==3){\nvar view = text.get(2).toString();\nif(view==\" \"){view =\"无\";}\nvar episode =text.get(0).toString();\nif(episode ==\" \"|| episode ==\"-\"){episode =\"无\";}\nresult = episode+\"   观看:\"+view}else if(text.size()==4){\nvar view = text.get(3).toString();\nif(view==\" \"){view =\"无\";}\nvar episode =text.get(0).toString();\nif(episode ==\" \"|| episode ==\"-\"){episode =\"无\";}\nresult = episode+\"   观看:\"+view\n}else{result = \"可通过动图预览查找动画\"}\n",
    "ruleTitle": "tag.div@id&&class.name@text",
    "singleUrl": false,
    "sortUrl": "搜索::https://www.hentaicloud.com/search?search_type=videos&search_query=&search_type=videos&page={{page}}\n\n\n动图::https://www.hentaicloud.com/gifs?page={{page}}\n3D::https://www.hentaicloud.com/videos/3d-hentai?page={{page}}\n口交::https://www.hentaicloud.com/tags/Blowjob?page={{page}}\n无码::https://www.hentaicloud.com/tags/Uncensored?page={{page}}\n触手::https://www.hentaicloud.com/tags/Tentacle?page={{page}}\n扶她::https://www.hentaicloud.com/videos/futanari?page={{page}}\n恶魔::https://www.hentaicloud.com/tags/Demon?page={{page}}\n自慰::https://www.hentaicloud.com/tags/Masturbation?page={{page}}\n后宫::https://www.hentaicloud.com/tags/Harem?page={{page}}",
    "sourceGroup": "4视频影视",
    "sourceIcon": "天",
    "sourceName": "2.8",
    "sourceUrl": "https://www.hentaicloud.com"
  },
  {
    "articleStyle": 2,
    "customOrder": 510,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; SM-S918B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36\",\n  \"Referer\": \"https://qikzj.com/\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": ".bricks-layout-item.repeater-item",
    "ruleContent": "@js:\nvar doc = org.jsoup.Jsoup.parse(result);\nvar myImgs = [];\n\n// 1. 严格锁定正文 ID，彻底避开 Related Posts 等外部组件\nvar contentHtml = \"\";\nvar mainBox = doc.getElementById(\"brxe-qoenez\");\nif (mainBox) {\n    contentHtml = mainBox.html();\n} else {\n    contentHtml = doc.select(\".brxe-post-content\").html();\n}\n\nif (contentHtml) {\n    // 2. 在限定范围内扫描高清图片链接\n    var regex = /https?:\\/\\/qikzj\\.com\\/wp-content\\/uploads\\/[^\"'\\s<>]*?\\.(?:jpg|jpeg|png|webp|gif)/gi;\n    var matches;\n    while ((matches = regex.exec(contentHtml)) !== null) {\n        var s = matches[0];\n        // 过滤 Logo 和头像\n        if (s.indexOf(\"logo\") === -1 && s.indexOf(\"avatar\") === -1) {\n            // 还原高清原图路径，去掉尺寸和缩放后缀\n            var cleanUrl = s.replace(/-\\d+x\\d+\\./i, \".\").replace(/-scaled\\./i, \".\");\n            if (myImgs.indexOf(cleanUrl) === -1) {\n                myImgs.push(cleanUrl);\n            }\n        }\n    }\n}\n\nvar displayTitle = (typeof title !== 'undefined' && title) ? title : \"QikZ Visuals\";\n\nvar h = \"<!DOCTYPE html><html><head><style>body{margin:0;background:#050505;color:#eee;font-family:sans-serif;padding-bottom:100px} .top{background:#111;color:#888;text-align:center;padding:15px;font-size:10px;text-transform:uppercase;letter-spacing:3px;border-bottom:1px solid #222} .header{padding:40px 25px;text-align:center} .img-list{padding:0 10px} .img-box{position:relative;margin-bottom:18px;background:#000;border-radius:2px;overflow:hidden;box-shadow:0 10px 30px rgba(0,0,0,0.5)} .img-box img{width:100%;display:block;height:auto} .img-num{position:absolute;bottom:10px;right:15px;background:rgba(0,0,0,0.6);color:#fff;padding:2px 8px;border-radius:2px;font-size:10px;font-family:monospace;font-weight:bold}</style></head><body>\";\nh += \"<div class='top'>HD VISUAL SHOWCASE</div>\";\nh += \"<div class='header'><h1 style='font-size:20px;margin:0;font-weight:300;color:#fff;line-height:1.4'>\" + displayTitle + \"</h1></div>\";\nh += \"<div class='img-list'>\";\nfor(var k=0; k<myImgs.length; k++){\n    h += \"<div class='img-box'><img src='\" + myImgs[k] + \"'><span class='img-num'>\" + (k+1) + \" / \" + myImgs.length + \"</span></div>\";\n}\nh += \"</div><p style='text-align:center;color:#333;font-size:10px;margin-top:60px;letter-spacing:2px'>QIKZ PHOTOGRAPHY GALLERY</p></body></html>\";\nresult = h;",
    "ruleImage": "@js:\nvar img = result.select(\"img\").first();\nif (img) {\n    var s = img.attr(\"data-src\") || img.attr(\"data-srcset\") || img.attr(\"src\");\n    if (s && s.indexOf(\" \") > 0) s = s.split(\" \")[0];\n    result = s;\n} else {\n    result = \"https://qikzj.com/favicon.ico\";\n}\nresult;",
    "ruleLink": "h3.dynamic a@href",
    "ruleNextPage": ".page-numbers.next@href",
    "ruleTitle": "h3.dynamic a@text",
    "singleUrl": false,
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://qikzj.com/favicon.ico",
    "sourceName": "3.2",
    "sourceUrl": "https://qikzj.com"
  },
  {
    "articleStyle": 1,
    "customOrder": 514,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; 2211133C Build/TKQ1.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Mobile Safari/537.36\"}",
    "lastUpdateTime": 1775586071363,
    "loadWithBaseUrl": true,
    "ruleArticles": ".grid_post-box",
    "ruleContent": "@js:\nlet images = [];\nlet regex = /<a\\s[^>]*?href\\s*=\\s*['\"]([^'\"]+\\.(?:jpe?g|png|gif|webp|bmp))['\"][^>]*>\\s*<img[^>]*>/gi;\nlet match;\nwhile ((match = regex.exec(result)) !== null) {\n    let realUrl = match[1];\n    images.push(`<img src=\"${realUrl}\" style=\"max-width:100%;display:block;margin:0px auto;\">`);\n}\nlet imageContent = images.join('');\nlet p = `\n<title>🏄Mengteen</title>\n<style>\n  * {margin: 0; padding: 0}\n  img {width: 100%;height: auto}\n  /* Mengteen阅图基础UI */\n  /* 返回按钮基础 */\n  #backToTopBtn {\n    display: none;\n    position: fixed;\n    bottom: 36px;\n    right: 18px;\n    z-index: 999;\n    border: none;\n    outline: none;\n    background: linear-gradient(135deg, #ADD8E6, #FFF8DC);\n    color: white;\n    cursor: pointer;\n    padding: 2px;\n    border-radius: 10%;\n    font-size: 18px;\n    box-shadow: 0 8px 32px rgba(70, 130, 180, 0.3);\n    transition: all 0.3s ease;\n    backdrop-filter: blur(4px);\n    border: 1px solid rgba(255, 255, 255, 0.3);\n  }\n  \n  #backToTopBtn:hover {\n    background: linear-gradient(135deg, #ADD8E6, #FFF8DC);\n    transform: scale(1.08);\n    box-shadow: 0 8px 25px rgba(70, 130, 180, 0.4);\n  }\n  \n  #backToTopBtn:active {\n    transform: scale(0.95);\n  }\n  \n  /* 图片加载完成提示基础 */\n  #image-loaded-toast {\n    position: fixed;\n    bottom: 33px;\n    left: 50%;\n    transform: translateX(-50%);\n    background: rgba(0, 0, 0, 0.7);\n    color: white;\n    padding: 10px 20px;\n    border-radius: 20px;\n    font-size: 14px;\n    z-index: 998;\n    backdrop-filter: blur(4px);\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n    opacity: 0;\n    transition: opacity 0.3s;\n    pointer-events: none;\n  }\n  \n  /* 标题卡片基础 */\n  #image-loaded-toast.show {\n    opacity: 1;\n  }\n</style>\n<div style=\"\n  text-align:center;\n  padding:50px 20px 20px;\n  margin:0 0 0px;\n  position:relative;\n  background:linear-gradient(135deg, #f0f7ff, #e6f0ff);\n\">\n  <!-- 标题卡片 -->\n  <div style=\"\n    position:relative;\n    z-index:10;\n    display:inline-block;\n    transform:translateY(-20px);\n    filter: drop-shadow(0 15px 25px rgba(70,130,180,0.25));\n  \">\n    <div style=\"\n      background:rgba(255,255,255,0.75);\n      backdrop-filter:blur(12px);\n      padding:16px 48px;\n      border-radius:18px;\n      border:1px solid rgba(255,255,255,0.5);\n      box-shadow:0 8px 32px rgba(70,130,180,0.2), inset 0 0 12px rgba(255,255,255,0.6);\n      position:relative;\n      overflow:hidden;\n    \">\n      <!-- 顶部高光 -->\n      <div style=\"\n        position:absolute;\n        top:0; left:0; right:0;\n        height:40%;\n        background:linear-gradient(to bottom, rgba(255,255,255,0.4), transparent);\n        pointer-events:none;\n      \"></div>\n      \n      <h3 style=\"\n        background:linear-gradient(135deg, #4a7bd0, #00a2b8);\n        -webkit-background-clip:text;\n        background-clip:text;\n        color:transparent;\n        font-size:1.3rem;\n        font-weight:700;\n        margin:0;\n        letter-spacing:-0.5px;\n        position:relative;\n        z-index:2;\n      \">{{@@h1@text}}</h3>\n      \n      <!-- 左下装饰点 -->\n      <div style=\"\n        position:absolute;\n        bottom:12px;\n        left:20px;\n        width:6px;\n        height:6px;\n        background:#00a2b8;\n        border-radius:50%;\n        opacity:0.7;\n      \"></div>\n      \n      <!-- 右下装饰点 -->\n      <div style=\"\n        position:absolute;\n        bottom:12px;\n        right:20px;\n        width:6px;\n        height:6px;\n        background:#4a7bd0;\n        border-radius:50%;\n        opacity:0.7;\n      \"></div>\n    </div>\n  </div>\n  \n  <!-- 时间信息 -->\n  <div style=\"\n    margin-top:0px;\n    padding:0px 20px;\n  \">\n    <h5 style=\"\n      color:#6c757d;\n      font-weight:400;\n      font-size:1rem;\n      margin:0;\n      line-height:1.6;\n      letter-spacing:0.3px;\n      position:relative;\n      display:inline-block;\n      max-width:700px;\n    \">\n      {{@@.post-meta-bottom@time.0@text}}\n      <!-- 下划线装饰 -->\n      <div style=\"\n        position:absolute;\n        bottom:-5px;\n        left:0;\n        width:100%;\n        height:1px;\n        background:linear-gradient(90deg, transparent, rgba(70,130,180,0.3), transparent);\n      \"></div>\n    </h5>\n  </div>\n  \n  <!-- 左上装饰圆 -->\n  <div style=\"\n    position:absolute;\n    top:10%;\n    left:15%;\n    width:40px;\n    height:40px;\n    border-radius:50%;\n    background:linear-gradient(135deg, rgba(74,123,208,0.1), transparent);\n    filter:blur(2px);\n  \"></div>\n  \n  <!-- 右下装饰圆 -->\n  <div style=\"\n    position:absolute;\n    bottom:15%;\n    right:10%;\n    width:60px;\n    height:60px;\n    border-radius:50%;\n    background:linear-gradient(135deg, rgba(0,162,184,0.1), transparent);\n    filter:blur(4px);\n    transform:rotate(30deg);\n  \"></div>\n</div>\n${imageContent}  <!-- 这里是图片内容 -->\n<div id=\"image-loaded-toast\">✅ 全部图片已完成加载</div>\n<button id=\"backToTopBtn\" title=\"回到顶部\">🔝</button>\n<script>\n(function() {\n  const backToTopBtn = document.getElementById(\"backToTopBtn\");\n  const toast = document.getElementById(\"image-loaded-toast\");\n  \n  // 图片加载完成检测\n  const images = document.querySelectorAll(\"img\");\n  let loadedCount = 0;\n  const totalImages = images.length;\n  \n  // 如果页面没有图片，直接隐藏提示\n  if(totalImages === 0) {\n    toast.style.display = \"none\";\n  }\n  \n  // 检测图片加载完成\n  images.forEach(img => {\n    if(img.complete) {\n      checkAllLoaded();\n    } else {\n      img.addEventListener(\"load\", checkAllLoaded);\n      img.addEventListener(\"error\", checkAllLoaded);\n    }\n  });\n  \n  function checkAllLoaded() {\n    loadedCount++;\n    if(loadedCount >= totalImages) {\n      showToast();\n    }\n  }\n  \n  function showToast() {\n    toast.classList.add(\"show\");\n    setTimeout(() => {\n      toast.classList.remove(\"show\");\n    }, 2000);\n  }\n  \n  // 监听页面滚动事件\n  window.addEventListener(\"scroll\", () => {\n    const scrollPosition = window.scrollY || document.documentElement.scrollTop;\n    \n    if (scrollPosition > 288) {\n      backToTopBtn.style.display = \"block\";\n      backToTopBtn.style.opacity = \"1\";\n    } else {\n      backToTopBtn.style.display = \"none\";\n    }\n  });\n  \n  // 点击事件监听器\n  backToTopBtn.addEventListener(\"click\", () => {\n    window.scrollTo({\n      top: 0,\n      behavior: \"smooth\"\n    });\n  });\n})();\n</script>\n`;\np;",
    "ruleImage": "img@data-src",
    "ruleLink": ".clearfix@data-href",
    "ruleNextPage": "page",
    "rulePubDate": "🏄Mengteen｜🔖{{@@.post-cat@text}}",
    "ruleTitle": "img@alt",
    "singleUrl": false,
    "sortUrl": "首页::/page/{{page}}/\n搜索::/page/{{page}}/?s={{(source.getVariable()==''||source.getVariable()==null)?source.setVariable('美女'):source.getVariable()}}\n女優画像::/category/avjoyuu/page/{{page}}/\n女高画像::/category/josikousei/page/{{page}}/\nおっぱい画像[美乳]::/category/oppai/page/{{page}}/\n太もも画像[美腿]::/category/hutomomo/page/{{page}}/\nオナニー画像[自慰]::/category/onani/page/{{page}}/\n野外セックス[野外啪啪]::/category/yagaisekkusu/page/{{page}}/\n乱交画像[群P]::/category/rankougazou/page/{{page}}/\nフェラ画像[口交]::/category/fera/page/{{page}}/\nクンニ画像[口交]::/category/kunnni/page/{{page}}/\nパイズリ画像[乳交]::/category/paizurigazou/page/{{page}}/\nレズ[女同]::/category/rezugazou/page/{{page}}/\nキス画像[接吻]::/category/kisugazou/page/{{page}}/\nSM::/category/smgazou/page/{{page}}/\n露出::/category/rosyutsugazou/page/{{page}}/\n偷拍::/category/tousatsugazou/page/{{page}}/\n素人::/category/sirouto/page/{{page}}/\n欧美::/category/gaizinerogazou/page/{{page}}/\n制服::/category/olgazou/page/{{page}}/\n泳衣::/category/mizugi/page/{{page}}/\n网袜::/category/amitaitsu/page/{{page}}/\n黑丝::/category/pannsuto/page/{{page}}/\n吊带::/category/ga-ta-beruto/page/{{page}}/\n浴衣::/category/yukatakimono/page/{{page}}/\n女仆::/category/meido/page/{{page}}/\n眼镜娘::/category/megane/page/{{page}}/",
    "sourceComment": "源社区：@Mengteen  2025.7.16\n二传二创或者是其它问题请联系我。\n我邮箱:[xxxmgqxxx@vip.qq.com]\n我QQ:99737563(备注来意)\n1.不需要挂🪜子,个别地方网络加载可能有点慢或者是需要挂🪜子才能访问，别急！\n2.使用了我自己的看图UI,卡片式标题,自适应全屏,一键返回顶上按钮,图片加载完成提示等。\n3.搜索和分类是按我自己个人喜欢的,你也可以放一些你自己喜欢的。",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://pashalism.com/wp-content/uploads/2022/03/2341-33.jpg",
    "sourceName": "3.5",
    "sourceUrl": "https://pashalism.com/##@Mengteen",
    "variableComment": "🏄Mengteen提示：在此输入关键词搜索！"
  },
  {
    "articleStyle": 0,
    "customOrder": 515,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "",
    "sourceName": "3.6",
    "sourceUrl": "http://www.mxshm.top"
  },
  {
    "articleStyle": 0,
    "contentBlacklist": "https://pc.stgowan.com/,\nhttps://dmku.mhtjx.top/,\nhttps://dmku.m3u8.pw/,\nhttps://dm.bbj.icu/,\nhttps://www.superplayer.top/index.php/index/dm",
    "coverDecodeJs": "function toByteArray(input) {\n  var out = new Packages.java.io.ByteArrayOutputStream();\n  var buffer = java.strToBytes('\\0'.repeat(4096));\n  var bytesRead;\n  while ((bytesRead = input.read(buffer)) != -1) {\n    out.write(buffer, 0, bytesRead);\n  }\n  return out.toByteArray();\n}\n\n(function() {\n  // 1. 读取原始字节内容\n  var textBytes = toByteArray(result);\n  // 2. 如果是GIF文件，直接返回原始字节\n  if (src.endsWith('.gif')) {\n    return textBytes;\n  }\n  try {\n    // 3. 将字节转换为字符串（用于解析数据URI）\n    var dataUri = java.bytesToStr(textBytes, \"UTF-8\");\n    // 4. 判断是完整的数据URI还是纯Base64数据\n    var base64Prefix = \"base64,\";\n    var base64Index = dataUri.indexOf(base64Prefix);\n    if (base64Index === -1) {\n      // 如果没有找到base64前缀，检查是否需要截取第一个/及之后的内容\n      var firstSlashIndex = dataUri.indexOf('/');\n      if (firstSlashIndex !== -1) {\n        // 如果找到第一个/，截取/及之后的内容\n        dataUri = dataUri.substring(firstSlashIndex);\n      }\n      // 对整个内容进行Base64解码\n      return java.base64DecodeToByteArray(dataUri);\n    } else {\n      // 如果是标准data URI，提取base64编码部分解码\n      var base64Data = dataUri.substring(base64Index + base64Prefix.length);\n      return java.base64DecodeToByteArray(base64Data);\n    }\n  } catch (e) {\n    // 解码失败时返回原始字节\n    return textBytes;\n  }\n})();",
    "customOrder": 517,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t\"User-Agent\":\"Mozilla/5.0 (Linux; U; Android 10; zh-cn; MI CC 11)  AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36 XiaoMi/MiuiBrowser/18.1.8 swan-mibrowser\",\n\t\"referer\": \"{{baseUrl}}\"\n}",
    "injectJs": "function setupCustomPlayer(video) {\n  // 手势滑动快进\n  let isDragging = false;\n  let startX = 0;\n  let startTime = 0;\n  \n  // 长按加速相关变量\n  let longPressTimer = null;\n  const LONG_PRESS_DELAY = 300;\n  const NORMAL_SPEED = 1.25;\n  const FAST_SPEED = 3;\n  let wasPaused = false;\n\n  // 触摸事件处理\n  function handleTouchStart(e) {\n    startX = e.touches[0].clientX;\n    startTime = video.currentTime;\n    wasPaused = video.paused;\n    \n    longPressTimer = setTimeout(() => {\n      video.playbackRate = FAST_SPEED;\n      if (wasPaused) video.play();\n    }, LONG_PRESS_DELAY);\n  }\n\n  function handleTouchMove(e) {\n    if (longPressTimer) {\n      clearTimeout(longPressTimer);\n      longPressTimer = null;\n    }\n    \n    const dx = e.touches[0].clientX - startX;\n    if (Math.abs(dx) > 10) {\n      if (!isDragging) {\n        video.pause();\n        isDragging = true;\n      }\n      const change = (dx / video.clientWidth) * video.duration;\n      video.currentTime = Math.max(0, Math.min(startTime + change, video.duration));\n    }\n  }\n\n  function handleTouchEnd() {\n    if (longPressTimer) {\n      clearTimeout(longPressTimer);\n      longPressTimer = null;\n    }\n    \n    if (isDragging) {\n      video.playbackRate = NORMAL_SPEED;\n      video.play();\n      isDragging = false;\n    } else if (video.playbackRate === FAST_SPEED) {\n      video.playbackRate = NORMAL_SPEED;\n      if (wasPaused) video.pause();\n    }\n  }\n\n  // 添加触摸事件监听\n  video.addEventListener('touchstart', handleTouchStart);\n  video.addEventListener('touchmove', handleTouchMove);\n  video.addEventListener('touchend', handleTouchEnd);\n  \n  // 初始播放速度\n  video.playbackRate = NORMAL_SPEED;\n\n  // 创建按钮的通用函数\n  function createButton(text, onClick, position, width = '20px') {\n    const button = document.createElement('button');\n    button.textContent = text;\n    button.style.position = 'absolute';\n    button.style[position.horizontal] = '0';\n    button.style.top = '50%';\n    button.style.transform = 'translateY(-50%)';\n    button.style.zIndex = '999';\n    button.style.padding = '1px';\n    button.style.background = 'rgba(51, 51, 51, 0)';\n    button.style.color = '#fff';\n    button.style.border = 'none';\n    button.style.cursor = 'pointer';\n    button.style.width = width;\n    button.style.height = '30px';\n    button.addEventListener('click', onClick);\n    video.parentNode.appendChild(button);\n    return button;\n  }\n\n  // 旋转按钮（右侧）\n  createButton('⟳', () => {\n    const currentRotation = parseInt(video.getAttribute('data-rotation') || '0');\n    const newRotation = (currentRotation + 90) % 360;\n    video.setAttribute('data-rotation', newRotation);\n    \n    // 保留当前的缩放比例\n    const currentTransform = video.style.transform || '';\n    let currentScale = 1;\n    const scaleMatch = currentTransform.match(/scale\\(([^)]+)\\)/);\n    if (scaleMatch) currentScale = parseFloat(scaleMatch[1]);\n    \n    video.style.transform = `rotate(${newRotation}deg) scale(${currentScale})`;\n  }, { horizontal: 'right' });\n\n  // 缩放按钮（左侧）\n  let zoomCount = 0;\n  createButton('+', () => {\n    const currentRotation = parseInt(video.getAttribute('data-rotation') || '0');\n    \n    // 获取当前缩放比例\n    const currentTransform = video.style.transform || '';\n    let currentScale = 1;\n    const scaleMatch = currentTransform.match(/scale\\(([^)]+)\\)/);\n    if (scaleMatch) currentScale = parseFloat(scaleMatch[1]);\n    \n    if (zoomCount < 4) {\n      const newScale = currentScale * 1.25;\n      video.style.transform = `rotate(${currentRotation}deg) scale(${newScale})`;\n      zoomCount++;\n    } else {\n      video.style.transform = `rotate(${currentRotation}deg) scale(1)`;\n      zoomCount = 0;\n    }\n  }, { horizontal: 'left' });\n\n  // 快速跳转按钮（底部中央）\n  const buttonContainer = document.createElement('div');\n  buttonContainer.style.position = 'absolute';\n  buttonContainer.style.bottom = '0';\n  buttonContainer.style.left = '50%';\n  buttonContainer.style.transform = 'translateX(-50%)';\n  buttonContainer.style.display = 'flex';\n  buttonContainer.style.gap = '10px';\n  buttonContainer.style.zIndex = '999';\n  \n  // 按钮配置\n  const seekButtons = [\n    { text: '-5分', time: -300 },\n    { text: '-1分', time: -60 },\n    { text: '+1分', time: 60 },\n    { text: '+5分', time: 300 }\n  ];\n\n  seekButtons.forEach(({ text, time }) => {\n    const button = document.createElement('button');\n    button.textContent = text;\n    button.style.padding = '1px';\n    button.style.background = 'rgba(51, 51, 51, 0)';\n    button.style.color = '#fff';\n    button.style.border = 'none';\n    button.style.cursor = 'pointer';\n    button.style.width = '60px';\n    button.style.height = '30px';\n    button.addEventListener('click', () => {\n      video.currentTime = Math.max(0, Math.min(video.currentTime + time, video.duration));\n    });\n    buttonContainer.appendChild(button);\n  });\n\n  video.parentNode.appendChild(buttonContainer);\n}\n\n// 修改初始化逻辑，增加重试机制\nfunction initPlayerWithRetry() {\n  const maxRetries = 10;\n  const retryInterval = 500;\n  let retries = 0;\n  const tryInit = () => {\n    const video = document.getElementById('video');\n    if (video) {\n      setupCustomPlayer(video);\n    } else if (retries < maxRetries) {\n      retries++;\n      setTimeout(tryInit, retryInterval);\n    }\n  };\n  tryInit();\n}\n// 使用重试机制初始化播放器\ninitPlayerWithRetry();",
    "lastUpdateTime": 1775584959581,
    "loadWithBaseUrl": true,
    "ruleArticles": "$.rescont.data",
    "ruleContent": "<html><head><meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no\" />\n<meta name=\"referrer\" content=\"never\"/>\n  <style>html, body {text-align: center;margin: 0; padding: 0;width: 100%;overflow: hidden;} </style>\n  <script src=\"https://unpkg.com/hls.js@1.4.3/dist/hls.min.js\"></script>\n</head><body>\n  <div class=\"container\">\n    <div class=\"title\">{{$.rescont.title}}</div>\n    <video id=\"video\" width=\"100%\" height=\"91%\" poster=\"\" controls autoplay muted loop></video>\n  </div>\n<script>\nconst v=document.getElementById('video'),s=[\n  \"{{$.rescont.videopath}}\",\n  \"\"];\nlet c=0;\nfunction setupCustomControls(e){/* 自定义功能实现 */}\nfunction playNext(){\n  c>=s.length&&(c=0); // 循环重置计数器\n  const u=s[c++];\n  // 检测Hls对象是否存在\n  if (typeof Hls !== 'undefined' && Hls.isSupported()) {\n    const h = new Hls({\n      enableSoftwareAES: true,          // 强制软件解密\n      forceKeyFrameOnDiscontinuity: true // 关键帧恢复\n    });\n    h.loadSource(u);\n    h.attachMedia(v);\n    h.on(Hls.Events.MANIFEST_PARSED,()=>v.play().then(()=>setupCustomControls(v)).catch(console.log));\n    h.on(Hls.Events.ERROR,(_,d)=>d.fatal&&playNext())\n  } else { // Hls加载失败或浏览器原生支持HLS\n    if (v.canPlayType('application/vnd.apple.mpegurl')) {\n      v.src = u;\n      v.onloadedmetadata = () => v.play().then(() => setupCustomControls(v));\n      v.onerror = playNext;\n    } else {\n      // 如果都不支持，尝试直接播放（可能支持MP4等格式）\n      v.src = u;\n      v.onerror = playNext;\n      v.play().then(() => setupCustomControls(v)).catch(playNext);\n    }\n  }\n}playNext();\n</script>\n</body></html>",
    "ruleImage": "{{$.coverbase64.url}}",
    "ruleLink": "/api/videoplay/{{$.id}}?uuid=1",
    "ruleNextPage": "$.rescont.next_page_url",
    "rulePubDate": "📆{{$.updated_at## .*}}  ⏱️{{$.playtimes}}",
    "ruleTitle": "$.title##.*屎.*|.*Ts.*|.*TS.*|.*ts.*|.*伪娘.*|.*人妖.*|.*男同.*|.*mbrba.*|.*水果派.*|.*解说.*|.*mmraa.*|.*ss-.*|.*fway.*|.*rebd.*|.*mbdd.*|.*双性.*|.*妈妈.*|.*儿子.*|.*爸爸.*|.*女儿.*|.*母子.*|.*父女.*|.*熟女.*|.*眼射.*|.*直男.*|.*CD.*|.*肥女.*|.*黄金.*|.*骚0.*|.*gv.*|.*父子.*|.*飞机.*|.*撸.*|.*厕.*|.*老阿姨.*|.*乱伦.*|.*[电影].*",
    "singleUrl": false,
    "sortUrl": "\n随机::/api/videosort/0?page={{ Math.ceil(Math.random()*1600) }}\n最新::/api/videosort/0?page={{page}}\n🔎搜索::/api/videosort/0?serach={{v=source.getVariable();if(/^\\s*$/.test(v)||v==null)source.setVariable('强奸');source.getVariable()}}&page={{page}}\n国产自拍::/api/videosort/28?page={{page}}\nH动漫::/api/videosort/32?page={{page}}\n3D动画::/api/videosort/65?page={{page}}\n国产AV::/api/videosort/68?page={{page}}\n高清无码::/api/videosort/30?page={{page}}\n凌辱侵犯::/api/videosort/60?page={{page}}\n性虐调教::/api/videosort/64?page={{page}}\n长腿丝袜::/api/videosort/43?page={{page}}\n制服诱惑::/api/videosort/33?page={{page}}\nAV素人::/api/videosort/39?page={{page}}\nAV剧情::/api/videosort/49?page={{page}}\n绿帽人妻::/api/videosort/58?page={{page}}\n痴女淫娃::/api/videosort/61?page={{page}}\n美乳巨乳::/api/videosort/38?page={{page}}\n草莓推荐::/api/videosort/52?page={{page}}\ntaipei1001::/api/videosort/69?page={{page}}\n259LUXU::/api/videosort/50?page={{page}}\n明星淫梦::/api/videosort/56?page={{page}}\n电车痴汉::/api/videosort/59?page={{page}}\n絕色佳人::/api/videosort/44?page={{page}}\n网红嫩模::/api/videosort/37?page={{page}}\n口交自慰::/api/videosort/63?page={{page}}\n精油汗汁::/api/videosort/62?page={{page}}\n角色扮演::/api/videosort/27?page={{page}}\n魔镜系列::/api/videosort/54?page={{page}}\n重咸口味::/api/videosort/48?page={{page}}\n三级电影:/api/videosort/46?page={{page}}\n家庭乱伦::/api/videosort/57?page={{page}}\nAV欧美::/api/videosort/36?page={{page}}\n恐怖情色::/api/videosort/51?page={{page}}\n酒店偷拍::/api/videosort/67?page={{page}}",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://i1.wp.com/i.postimg.cc/wjL5myHr/kpptube-cc-3e997cb42a6b0f37af6c6a40866ba202.gif",
    "sourceName": "3.7",
    "sourceUrl": "https://api.cmapiaba.xyz/",
    "style": ".container {\n    position: relative; /* 相对定位，用于包含视频 */\n    height: 100%; /* 容器高度与视频原始高度相同 */\n    overflow: hidden; /* 隐藏超出容器的部分 */\n}\n.title {\n    position: absolute; /* 绝对定位，相对于容器 */\n    top: 0; \n    width: 100%;\n    overflow: hidden; \n    text-overflow: ellipsis;\n    display: -webkit-box;\n    -webkit-box-orient: vertical; \n    -webkit-line-clamp: 2;\n    z-index: 1; /* 确保标题在视频之上 */\n    background: #000; /* 纯黑色背景 */ \n    padding: 0 0 3px 0;\n}\nvideo {\n    position: absolute; /* 绝对定位，相对于容器 */ \n    top: -65px; /* 上移80px */\n    left: 0; \n    width: 100%; \n    height: calc(96% + 65px);  /* 调整高度以适应内容 */\n    object-fit: contain; /* 确保视频内容不被裁剪 */\n    z-index: 0; /* 确保视频在标题之下 */\n    controls=\"controls\" autoplay muted; \n} \n"
  },
  {
    "articleStyle": 0,
    "customOrder": 518,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "3.8",
    "sourceUrl": "http://www.hjtaotu.com/chis/gufeng/1.html"
  },
  {
    "articleStyle": 2,
    "customOrder": 519,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "//div.list-com/a",
    "ruleContent": "//ul/li",
    "ruleImage": "//img@src##.*?<img src=\"(.*?)\".*?##$1###@js:header={\"Referer\":baseUrl}\nheaders={\"headers\":JSON.stringify(header)}\nresult=result+','+JSON.stringify(headers)",
    "ruleLink": "href",
    "ruleNextPage": "page",
    "rulePubDate": "//img@src##.*?<img src=\"https://imgfzone.tooopen.com/(.*?)/.*?.jpg\".*?##$1###",
    "ruleTitle": "//text()",
    "singleUrl": false,
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "3.9",
    "sourceUrl": "https://desk.tooopen.com/beauty_3<,_{{page}}>.html"
  },
  {
    "articleStyle": 2,
    "customOrder": 520,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "//div.list-com/a",
    "ruleContent": "//ul/li",
    "ruleImage": "//img@src##.*?<img src=\"(.*?)\".*?##$1###@js:header={\"Referer\":baseUrl}\nheaders={\"headers\":JSON.stringify(header)}\nresult=result+','+JSON.stringify(headers)",
    "ruleLink": "href",
    "ruleNextPage": "page",
    "rulePubDate": "//img@src##.*?<img src=\"https://imgfzone.tooopen.com/(.*?)/.*?.jpg\".*?##$1###",
    "ruleTitle": "//text()",
    "singleUrl": false,
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "4.0",
    "sourceUrl": "https://desk.tooopen.com/artphoto_3<,_{{page}}>.html"
  },
  {
    "articleStyle": 0,
    "customOrder": 522,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "singleUrl": true,
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://m.acgnfl.com/24/07/content_33/525867/087.webp",
    "sourceName": "4.2推荐",
    "sourceUrl": "https://xrhf.taimei-t140.vip/"
  },
  {
    "articleStyle": 1,
    "customOrder": 523,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "article",
    "ruleContent": ".Content@img@src\n<js>\nli='\\n'\nlist=result.split('\\n')\nfor(i in list){\n\t\tli += '<li><img src=\"https://i01piccdn.sogoucdn.com/b9e03099a48fd4ad\" data-src=\"'+list[i]+'\"></li>\\n'\n\t}\nli\n</js>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n\n\n<ul id=\"box\">\n{{result}}\n</ul>\n\n\n<link rel=\"stylesheet\" href=\"https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.css\">\n<script src=\"https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.js\"></script>\n<script>\n\troot = document.getElementById('box')\n\tlazy = new IntersectionObserver(entires => {\n\t\tentires.forEach(item => {\n\t\t\tif(item.isIntersecting){\n\t\t\t\titem=item.target\n\t\t\t\titem.src=item.getAttribute('data-src')\n\t\t\t\tlazy.unobserve(item)\n\t\t\t}\n\t\t})\n\t}, {\n\t\troot: root,\n\t\tthreshold: [0],\n\t\trootMargin:\"0px 0px 500px 0px\"\n\t})\n\nimgs = document.getElementsByTagName('img')\nArray.from(imgs).forEach(item => {\n\t\tlazy.observe(item)\n\t})\n\n//查看大图插件\nnew Viewer(root,{title:false,interval:3000})\n</script>",
    "ruleImage": "img@src",
    "ruleLink": "a@href",
    "ruleNextPage": ".pagelist@a@href",
    "ruleTitle": "h2@text",
    "singleUrl": false,
    "sortUrl": "首页::/\n肉丝 ::/tags-rousi-9sw.html\n黑丝 ::/tags-heisi-z2n.html\n白丝 ::/tags-baisi-v9l.html\n灰丝 ::/tags-huisi-z20.html\n咖丝 ::/tags-kasi-um6.html\n网袜 ::/tags-wangwa-18v.html",
    "sourceComment": "专注分享高清无水印的丝袜写真",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "4.3",
    "sourceUrl": "https://siwake.cc/",
    "style": "* {\n\tmargin: 0;\n\tpadding: 0\n}\nul {\n\tfont-size: 0;\n\theight: 100%;\n\toverflow-y: scroll\n}\nli {\n\tlist-style: none;\n\ttext-align: center\n}\nimg {\n\twidth: 98%;\n\theight: auto;\n\tpadding: 1% 1% 0 1%\n}"
  },
  {
    "articleStyle": 0,
    "customOrder": 524,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "class.pb@tag.div",
    "ruleImage": "class.focus@tag.span@tag.img@src",
    "ruleNextPage": "class.pagination pagination-multi@class.next-page@tag.a@href",
    "rulePubDate": "class.text-muted time.0@text##发布于:",
    "ruleTitle": "class.excerpt excerpt-one.0@tag.header@tag.a@text",
    "singleUrl": true,
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://www.xx3004.vip/wp-content/themes/xiu/images/wap-logo.png",
    "sourceName": "4.4",
    "sourceUrl": "https://www.san421.com/meinv"
  },
  {
    "articleStyle": 2,
    "customOrder": 525,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "id.main@tag.li||$",
    "ruleContent": "id.allbtn@text##展开全图\\(1/|\\)\n<js>\nn=Number(result)+1\nu='{{@@id.nowimg@src##1\\.jpg$}}'\n\nlist='\\n'\nfor(i=1;i<n;i++){\n\t\tlist += '<li><img src=\"https://www.tuiimg.com/images/logo.png\" data-src=\"'+u+i+'.jpg\"></li>\\n'\n\t}\nlist\n</js>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n\n\n<ul id=\"box\">\n{{result}}\n</ul>\n\n\n<link rel=\"stylesheet\" href=\"https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.css\">\r\n<script src=\"https://cdn.bootcdn.net/ajax/libs/viewerjs/1.10.1/viewer.min.js\"></script>\n<script>\n\troot = document.getElementById('box')\n\tlazy = new IntersectionObserver(entires => {\n\t\tentires.forEach(item => {\n\t\t\tif(item.isIntersecting){\n\t\t\t\titem=item.target\n\t\t\t\titem.src=item.getAttribute('data-src')\n\t\t\t\tlazy.unobserve(item)\n\t\t\t}\n\t\t})\n\t}, {\n\t\troot: root,\n\t\tthreshold: [0],\n\t\trootMargin:\"0px\"\n\t})\n\nimgs = document.getElementsByTagName('img')\nArray.from(imgs).forEach(item => {\n\t\tlazy.observe(item)\n\t})\n\n//查看大图插件\nnew Viewer(root,{title:false,interval:3000})\n</script>",
    "ruleImage": "tag.img@realsrc\n@js:\nresult?result:'https://i.tuiimg.net/{{$.catalog}}/{{$.id}}/mc.jpg'",
    "ruleLink": "tag.a@href\n@js:\nresult?result:'https://m.tuiimg.com/meinv/{{$.id}}/'",
    "ruleNextPage": "page",
    "rulePubDate": "{{$.time}}{{@@tag.span.0@text## 发布}} 发布　　喜欢({{$.love}}{{@@tag.span.1@text##(\\d+)##$1###}})",
    "ruleTitle": "tag.h2@text||$.title",
    "singleUrl": false,
    "sortUrl": "首页最新::https://m.tuiimg.com/data.php?page={{page}}\n性感美女::https://m.tuiimg.com/xingganmeinv/list_{{page}}.html\n清纯美女::https://m.tuiimg.com/qingchunmeinv/list_{{page}}.html\n妹子图集::https://m.tuiimg.com/meizitu/list_{{page}}.html\n美女写真::https://m.tuiimg.com/meinvxiezhen/list_{{page}}.html\n\n\n//标签\n美胸::https://m.tuiimg.com/tag/meixiong/list_{{page}}.html\n美臀::https://m.tuiimg.com/tag/meitun/list_{{page}}.html\n美腿::https://m.tuiimg.com/tag/meitui/list_{{page}}.html\n妩媚::https://m.tuiimg.com/tag/wumei/list_{{page}}.html\n爆乳::https://m.tuiimg.com/tag/baoru/list_{{page}}.html\n诱惑::https://m.tuiimg.com/tag/youhuo/list_{{page}}.html\n丰满::https://m.tuiimg.com/tag/fengman/list_{{page}}.html\n可爱::https://m.tuiimg.com/tag/keai/list_{{page}}.html\n嫩模::https://m.tuiimg.com/tag/nenmo/list_{{page}}.html\n甜美::https://m.tuiimg.com/tag/tianmei/list_{{page}}.html\n萌妹::https://m.tuiimg.com/tag/mengmei/list_{{page}}.html\n\n\n//平台\nROSI::https://m.tuiimg.com/rosi/list_{{page}}.html\n秀人网::https://m.tuiimg.com/xiuren/list_{{page}}.html\n尤蜜荟::https://m.tuiimg.com/tag/youmihui/list_{{page}}.html\n尤果网::https://m.tuiimg.com/tag/ugirls/list_{{page}}.html\n美媛馆::https://m.tuiimg.com/tag/myg/list_{{page}}.html\n魅妍社::https://m.tuiimg.com/tag/mistar/list_{{page}}.html\n爱蜜社::https://m.tuiimg.com/tag/imiss/list_{{page}}.html\n蜜桃社::https://m.tuiimg.com/tag/miitao/list_{{page}}.html\n模范学院::https://m.tuiimg.com/tag/mfstar/list_{{page}}.html\n尤物馆::https://m.tuiimg.com/tag/youwu/list_{{page}}.html\n星颜社::https://m.tuiimg.com/tag/xingyan/list_{{page}}.html\n嗲囡囡::https://m.tuiimg.com/tag/feilin/list_{{page}}.html\n花の颜::https://m.tuiimg.com/tag/huayan/list_{{page}}.html\n御女郎::https://m.tuiimg.com/tag/dkgirl/list_{{page}}.html\n花漾::https://m.tuiimg.com/tag/huayang/list_{{page}}.html\n网红馆::https://m.tuiimg.com/tag/candy/list_{{page}}.html\n第四印象::https://m.tuiimg.com/tag/disi/list_{{page}}.html\n头条女神::https://m.tuiimg.com/tag/toutiaogirls/list_{{page}}.html\n\n\n//更多分类请自己添加\n//https://m.tuiimg.com/tag/",
    "sourceComment": "v0.2\n更改正文模板\n优化key的获取\n\n\n原图标\nhttps://m.tuiimg.com/favicon.ico\n\n\n分类URL\n综合全部::https://m.tuiimg.com/meinv/list_{{page}}.html\n变量搜索::https://m.tuiimg.com/search/list_{{page}}.html,{'method':'POST','body': 'skey={{v=source.getVariable();(v!='',v!=null)?v:(source.setVariable('三度'),source.getVariable())}}'}",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "4.5",
    "sourceUrl": "@js:\npage=org.jsoup.Jsoup.parse(\n\tjava.ajax('https://m.tuiimg.com/meinv')\n).select('.end').attr('href').match(/\\d+/)[0]\n'https://m.tuiimg.com/meinv/list_' + Math.ceil(Math.random()*page) + '.html'",
    "style": "* {\n\tmargin: 0;\n\tpadding: 0\n}\nul {\n\tfont-size: 0;\n\theight: 100%;\n\toverflow-y: scroll\n}\nli {\n\tlist-style: none;\n\ttext-align: center\n}\nimg {\n\twidth: 100%;\n\theight: auto\n}"
  },
  {
    "articleStyle": 1,
    "customOrder": 529,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "@js:\nJSON.stringify({\n  'User-Agent': \"Mozilla/5.0 (Linux; Android 15; V2304A Build/AP3A.240905.015.A2; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.163 Mobile Safari/537.36\",\n  'sec-ch-ua-platform': \"\\\"Android\\\"\",\n  'X-Requested-With': \"XMLHttpRequest\",\n  'Referer': \"https://cn.royalcams.com/female/tags/recordable\",\n  'Connection':\"keep-alive\",\n  'Accept-language': \"zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7\"\n})",
    "lastUpdateTime": 1771719337202,
    "loadWithBaseUrl": true,
    "ruleArticles": "models[*]",
    "ruleImage": "{$.thumb_image}@js:result.replace(/{ext}/g, 'jpg')",
    "ruleLink": "https://{$.esid}.bcvcdn.com/hls/stream_{$.username}/playlist.m3u8",
    "ruleNextPage": "page",
    "rulePubDate": "👥 观众: {$.viewers}⭐ 粉丝: {$.f}",
    "ruleTitle": "$.display_name",
    "singleUrl": false,
    "sortUrl": "所有::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36\n青少年18::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=teens-18\n中等乳房::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=medium-tits\n波霸::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=big-tits\n超级波霸::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=huge-tits\n主妇::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=housewives\n亚洲::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=asian\n无毛::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=shaved-pussy\n大学生::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=college-girls\n大屁股::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=big-ass\n白人女孩::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=white-girls\n娇小体型::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=petite\n平胸::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=72&category=small-tits\n拉丁裔::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=latina\n捆绑::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=bondage\n曲线美::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=curvy\n潮喷::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=squirt\n熟女::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=mature\n物神::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=fetish\n玩具::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=toys\n红发::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=redhead\n肛交::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=anal\n褐色女郎::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=brunette\n辣妹::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=babes\nBBW::https://cn.royalcams.com/tools/listing_v3.php?livetab=female&is_mobile=true&offset={{(page-1)*36}}&limit=36&category=bbw\n多人::https://cn.royalcams.com/tools/listing_v3.php?livetab=couples&is_mobile=true&offset={{(page-1)*36}}&limit=36",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://i.wlicdn.com/wl/000/000/193/c0c5540e263feee85fbb8da2b1a888ca.png",
    "sourceName": "4.9",
    "sourceUrl": "https://cn.royalcams.com"
  },
  {
    "articleStyle": 2,
    "customOrder": 531,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": ".main@li",
    "ruleContent": "all##ul##details",
    "ruleImage": "img@realsrc",
    "ruleLink": "a@href",
    "ruleNextPage": "page",
    "rulePubDate": "{{@@.love@text}} {{@@span@text}}",
    "ruleTitle": "a@text",
    "singleUrl": false,
    "sortUrl": "性感美女::https://m.tuiimg.com/xingganmeinv/list_{{page}}.html\n清纯美女::https://m.tuiimg.com/qingchunmeinv/list_{{page}}.html\n妹子图::https://m.tuiimg.com/meizitu/list_{{page}}.html\n美女写真::https://m.tuiimg.com/meinvxiezhen/list_{{page}}.html",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "天",
    "sourceName": "5.1",
    "sourceUrl": "https://m.tuiimg.com"
  },
  {
    "articleStyle": 0,
    "customOrder": 533,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "header": "{\n\"User-Agent\": \"Mozilla/5.0 (Linux; U; Android 8.1.0; zh-CN; MI 8 Lite Build/OPM1.171019.019) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 UCBrowser/13.2.0.1100 Mobile Safari/537.36\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "li",
    "ruleLink": "text.一键导入@onclick",
    "rulePubDate": "span@text",
    "ruleTitle": "a@text",
    "singleUrl": true,
    "sourceGroup": "3小说漫画",
    "sourceIcon": "https://m.acgnfl.com/24/07/content_33/525867/007.webp",
    "sourceName": "5.2",
    "sourceUrl": "https://www.kxmanhua1.com/manga/library"
  },
  {
    "articleStyle": 3,
    "customOrder": 553,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 1775588705888,
    "loadWithBaseUrl": true,
    "ruleArticles": ".item",
    "ruleContent": "id.kt_player@all&&script@all",
    "ruleImage": "img@data-original",
    "ruleLink": "a@href",
    "ruleNextPage": "page",
    "rulePubDate": ".time@span",
    "ruleTitle": "img@alt",
    "singleUrl": false,
    "sortUrl": "搜索::https://www.85xo.com/search/{{v=source.getVariable()}}/\n亚洲人::/tags/ya-zhou-ren/\n马来::/tags/ma-lai/\n日本::/tags/ri-ben/\n后入::/tags/hou-ru/\n大奶::/tags/da-nai/\n高潮::/tags/gao-chao/\n做爱::/tags/zuo-ai/\n马来西亚::/tags/ma-lai-zi-ya/\n妹妹::/tags/mei-mei/\n兔牙::/tags/tu-ya/\n妹::/tags/mei/\n巨乳::/tags/ju-ru/\n自慰::/tags/zi-wei/\n情侣::/tags/qing-lv/\n骚::/tags/sao/\n男友::/tags/nan-you/\n淫叫::/tags/yin-jiao/\n抓奶::/tags/zhua-nai/\n新加坡::/tags/xin-jia-po/\n内衣::/tags/nei-yi/\n肉棒::/tags/rou-bang/\n床上::/tags/chuang-shang/\n嫩逼::/tags/nei-bi/\n日本人::/tags/ri-ben-ren/\n鲍鱼::/tags/bao-yu/\n口::/tags/kou/\n少女::/tags/shao-nv/\n美女::/tags/mei-nv/\n台灣::/tags/tai-wan/\n可爱::/tags/ke-ai/\n偷拍::/tags/tou-pai/\n掰逼::/tags/bai-bi/\n喷水::/tags/pen-shui/\n脱衣::/tags/tuo-yi/\n屁眼::/tags/pi-yan/\n口交::/tags/kou-jiao/\n高中::/tags/gao-zhong/\n妹子::/tags/mei-zi/\n中國::/tags/zhong-guo/\n母狗::/tags/mu-gao/\n全裸::/tags/quan-luo/\n美臀::/tags/mei-tun/\n贫乳::/tags/pin-ru/\n逼::/tags/bi/\n内裤::/tags/nei-ku/\n爱::/tags/ai/\n自拍::/tags/zi-pai/\n学生::/tags/xue-sheng/\n呻吟::/tags/shen-yin/\n韓國::/tags/han-guo/\n泰國::/tags/tai-guo/\n越南::/tags/yue-nan/\n近拍::/tags/jin-pai/\n香港::/tags/xiang-gang/\n新馬::/tags/xin-ma/\n街拍::/tags/jie-pai/",
    "sourceComment": "https://www.85po.com",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://85tube.com/favicon.ico",
    "sourceName": "6.4",
    "sourceUrl": "https://www.85xo.com/",
    "style": "{background-color:black;margin:0;padding:0;width:100%;}"
  },
  {
    "articleStyle": 3,
    "customOrder": 557,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 1775591744706,
    "loadWithBaseUrl": true,
    "ruleArticles": "ul@li",
    "ruleContent": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<title>内容提取</title>\n<!-- v2025.05.10 -->\n\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.css\" />\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.js\"></script>\n<style>\n    body { font-family: Arial, sans-serif; font-size: 16px; }\n    #title, #page, #loading-status { margin: 0 auto; font-size: 20px; text-align: center; }\n    #description, #urls, #video-url, #video-sources, #messages { width: 100%; max-width: 800px; margin: 1.5px auto; font-size: 14px; text-align: left; word-wrap: break-word; white-space: pre-wrap; }\n    #text, #text :not(img), #text img + * { text-indent: 2em; width: 100%; font-size: 16px; line-height: 1.5em; margin-top: 0; margin-bottom: 0; word-wrap: break-word; white-space: pre-wrap; }\n    img, #text img { width: 100%; height: auto; display: block; margin-bottom: 1.5px; }\n    .flex-container { display: flex; justify-content: center; align-items: center; gap: 10px; margin: 1.5px 0; font-size: 14px; }\n    button, select { flex: 1 1 31%; padding: 3px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; cursor: pointer; background-color: #f9f9f9; transition: background-color 0.3s ease; margin: 1.5px; min-width: 0; font-size: 14px; }\n    #url-select, #video-source-select { flex: 1 1 100%; margin-left: 0; margin-right: 0; text-align: center; }\n    #video-element { width: 100%; height: auto; }\n    textarea { width: 100%; height: auto; min-height: 100px; box-sizing: border-box; resize: vertical; }\n    .error, .warn { color: red; }\n</style>\n</head>\n<body>\n    <h3 id=\"title\">{{@@title@text||h1.0@text||h2.0@text||.title.0@text}}</h3>\n    <p id=\"description\">{{@@.info.0@html||.jianjie@html}}</p>\n    <p id=\"page\" style=\"display:none;\">共<span id=\"total-pages\">1</span>页</p>\n    <p id=\"loading-status\" style=\"display:none;\"></p>\n\n    <div class=\"flex-container\" id=\"loading-buttons\" style=\"display:none;\">\n        <button id=\"prev-page-btn\">上一页</button>\n        <button id=\"next-page-btn\">下一页</button>\n        <button id=\"auto-load-btn\">自&nbsp;&nbsp;动</button>\n    </div>\n    \n    <div class=\"flex-container\">\n        <select id=\"url-select\" style=\"display:none;\"></select>\n    </div>\n    \n    <div class=\"flex-container\">\n        <button id=\"toggle-urls-btn\">显/隐网址</button>\n        <button id=\"toggle-messages-btn\">显/隐信息</button>\n        <button id=\"toggle-debug-btn\">显/隐调试</button>\n    </div>\n    <div id=\"urls\"></div>\n    <div id=\"messages\"></div>\n    <div id=\"debug-info\"></div>\n    <div id=\"video-url\"></div>\n    <div id=\"video-container\" style=\"display: none;\">\n        <video id=\"video-element\" controls preload=\"auto\" width=\"640\" height=\"264\">\n            <source id=\"video-source\" src=\"\" type=\"\">您的浏览器不支持 video 标签。\n        </video>\n    </div>\n    <div class=\"flex-container\" id=\"video-source-container\" style=\"display: none;\">\n        <select id=\"video-source-select\" onchange=\"updateVideoSource()\"></select>\n    </div>\n    <div id=\"images\"></div>\n    <div id=\"text\"></div>\n\n    <script>\n        // 配置对象，包含各种选择器、延迟时间等配置项\n        const config = {    \n            videoSelector: 'body', // 视频选择器\n            imgSelector: '.gridlane-box-inside img,.photos figure img,.content p img', // 图片选择器\n            textSelector: '#content', // 文本选择器\n            debugSelector: '#content, .page, .pager, .content, script', // 调试信息选择器\n            swapImageAttributes: false, // 是否交换图片属性\n            delayTime: 1500, // 延迟提取时间\n            retryDelayTime: 1500, // 重试加载延迟时间\n            maxLoadAttempts: 3, // 最大加载次数\n            autoLoading: false, // true自动模式，false单页模式\n            debugOnce: 0, // 只在特定索引输出一次调试信息\n            totalPagesText: '{{@@.page.0@a.-2@textNodes}}', // 总页码\n            urlSuffixToRemove: /\\.html$/, // 移除url后缀\n            pageUrlText: '{urlPrefix}_{i}.html', // 拼接URL模板        \n            ListMode: true, // true网址列表模式，false网址拼接模式    \n            initialUrls: `{{@@#sort-item-5.0@a@href}}`, // 网址\n            initialUrlsName: `{{@@#sort-item-5.0@a@span@text}}`, // 网址名称\n            sourceurl: '', // 来源URL前缀\n        };\n\n        let videoSources = []; // 存储视频源数组\n        let loadAttempts = {}; // 记录每个URL的加载尝试次数\n        let urls = []; // 存储所有页面的URL\n        let imageBox;\n        let textBox;\n        let currentPageIndex = 0; // 当前页面索引\n        let canLoadNextPage = true; // 控制是否可以加载下一页\n        let autoLoadInProgress = false; // 自动加载状态\n\n        // 构建URL列表\n        function buildUrls(totalPages, baseUrl) {\n            let initialUrlsArray = config.initialUrls.trim().split('\\n').filter(url => url.trim() !== '');\n            let initialUrlsNameArray = config.initialUrlsName.trim().split('\\n').filter(name => name.trim() !== '');\n\n            if (config.ListMode && initialUrlsArray.length > 0) {\n                if (initialUrlsArray.length !== initialUrlsNameArray.length) {\n                    $('#messages').append(`<span class=\"warn\">警告：initialUrls 和 initialUrlsName 的长度不匹配。</span><br>`);\n                }\n\n                urls = initialUrlsArray.map(url => {\n                    if (config.sourceurl && url.startsWith('/') && !/^https?:\\/\\//i.test(url)) {\n                        return config.sourceurl.replace(/\\/$/, '') + url;\n                    } else {\n                        return url;\n                    }\n                });\n\n                urls.forEach((url, index) => {\n                    const name = initialUrlsNameArray[index] || `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            } else {\n                if (totalPages === 1) {\n                    urls.push(baseUrl);\n                } else {\n                    urls.push(baseUrl);\n                    for (let i = 2; i <= totalPages; i++) {\n                        urls.push(config.pageUrlText.replace('{urlPrefix}', baseUrl.replace(config.urlSuffixToRemove, '').replace(/\\/$/, '')).replace('{i}', i));\n                    }\n                }\n\n                urls.forEach((url, index) => {\n                    const name = `第 ${index + 1} 页`;\n                    $('#url-select').append(`<option value=\"${index}\">${name}</option>`);\n                    $('#urls').append(`<div>${name}: ${url}</div>`);\n                });\n            }\n\n            $('#total-pages').text(urls.length);\n            toggleNavigationButtons();\n            toggleTotalPagesDisplay();\n        }\n\n        // 规范化URL\n        function normalizeUrl(url) {\n            if (typeof url !== 'string' || !url.trim()) {\n                return '';\n            }\n            const match = url.match(/['\"](.*?)['\"]/);\n            if (match && match[1]) {\n                url = match[1];\n            }\n\n            function processUrl(str) {\n                str = str.trim();\n                str = str.replace(/\\\\u[\\dA-F]{4}/gi, match => String.fromCharCode(parseInt(match.replace(/\\\\u/g, ''), 16)));\n                str = decodeURIComponent(str);\n                str = str.replace(/^http:\\/([^/])/, 'http://$1');\n                str = str.replace(/^https:\\/([^/])/, 'https://$1');\n                return str;\n            }\n            return processUrl(url);\n        }\n\n        // 清空容器内容\n        function clearContainers() {\n            $('#messages').empty();\n            $('#images').empty();\n            $('#text').empty();\n        }\n\n        // 更新图像源\n        function updateImageSrc(elements, shouldSwap) {\n            elements.each(function () {\n                const $this = $(this);\n                const attrsToUpdate = {};\n                if (shouldSwap) {\n                    ['data-original', 'data-src', 'data-url'].forEach(attr => {\n                        if ($this.attr(attr)) {\n                            attrsToUpdate['src'] = $this.attr(attr);\n                        }\n                    });\n                }\n                $this.attr(attrsToUpdate);\n            });\n            return elements;\n        }\n\n        // 切换导航按钮显示状态\n        function toggleNavigationButtons() {\n            if ($('#url-select option').length > 1 && !config.autoLoading) {\n                $('#loading-buttons').show();\n                $('#url-select').show();\n            } else {\n                $('#loading-buttons').hide();\n                $('#url-select').hide();\n            }\n        }\n\n        // 显示加载状态\n        function showLoadingStatus(pageNumber) {\n            const selectedOption = $('#url-select option:selected').text();\n            $('#loading-status').text(`正在加载：${selectedOption}`).show();\n        }\n\n        // 隐藏加载状态\n        function hideLoadingStatus() {\n            $('#loading-status').hide();\n        }\n\n        // 加载指定索引的内容\n        function loadContent(index) {\n            if (index < 0 || index >= urls.length || !canLoadNextPage) return;\n            canLoadNextPage = false;\n            currentPageIndex = index;\n            $('#url-select').val(index);\n            $('#messages').append(`<div>当前地址: <span class=\"warn\">${urls[index]}</span></div>`);\n            if (autoLoadInProgress) {\n                showLoadingStatus(index + 1);\n            }\n            $.ajax({\n                url: urls[index],\n                type: 'GET',\n                success: function (data) {\n                    try {\n                    const $data = $(data);\n                    let updatedHtmlContent = data.replace(/(['\"])(\\/\\/)(?!\\/)/g, '$1https://')\n                        .replace(/src=\"upload/gi, 'src=\"/upload')\n                        .replace(/style=[\"'][^'\"]+[\"']/gi, '')\n                        .replace(/\\\\\\//g, '/');\n                    const parser = new DOMParser();\n                    const doc = parser.parseFromString(updatedHtmlContent, \"text/html\");\n\n                    if (config.debugOnce === index) {\n                        const debugElements = $(doc).find(config.debugSelector);\n                        if (debugElements.length > 0) {\n                            const debugContents = $('<pre>').html(debugElements.clone().wrapAll('<div/>').parent().html()).html();\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">${debugContents}</textarea></span>`);\n                        } else {\n                            $('#debug-info').html(`<span class=\"warn\">调试信息: <textarea rows=\"10\" cols=\"80\">调试信息未提取到内容，请检查选择器！</textarea></span>`);\n                        }\n                    }\n                    // 方法1：提取视频\n                    const videoSources1 = [];\n                    const videoContents = $(doc).find(config.videoSelector);\n                    const videoTags = $(videoContents).find('video, source');\n                    videoTags.each(function() {\n                        const videosrc = $(this).attr('src') || \n                                     $(this).attr('data-src') || \n                                     $(this).attr('data-original') || '';\n                        \n                        if (videosrc) {\n                            videoSources1.push(videosrc);\n                        }\n                    });\n                    //反馈\n                    if (videoSources1.length > 0) {\n                        $('#messages').append(`<span>方法1，找到 ${videoSources1.length} 个视频。</span><br>`);\n                    }\n\n                    // 方法2：正则提取视频\n                    const regex = /['\"]https?[^'<>\"]+(m3u8|mp4|webm|ogg|flv|mp3|m4a|wav|ape|flac)([^'<>\"]+)?['\"]/gi;\n                    const matches = data.match(regex);\n                    const videoSources2 = [];\n\n                    if (matches) {\n                        const uniqueMatches = [...new Set(matches)];\n                    \n                        uniqueMatches.forEach(match => {\n                            const normalizedSrc = normalizeUrl(match.replace(/['\"]/g, ''));\n                            videoSources2.push(normalizedSrc);\n                        });\n                    }\n                    //反馈\n                    if (videoSources2.length > 0) {\n                        $('#messages').append(`<span>方法2，找到 ${videoSources2.length} 个视频。</span><br>`);\n                    }\n\n                    // 合并两种方法的结果\n                    videoSources = [...videoSources1, ...videoSources2];\n\n                    // 去重并标准化 URL\n                    const imageExtensions = /\\.(jpg|jpeg|png|gif|bmp|svg)$/i;\n\n                    videoSources = videoSources\n                                  .map(src => normalizeUrl(src.replace(/\\\\+/g, '')))\n                                  .filter(src => src) // 过滤空值\n                                  .filter(src => !imageExtensions.test(src)); // 移除图片地址\n                        \n                    videoSources = [...new Set(videoSources)];// 去重\n\n                    // 显示最终结果\n                    $('#messages').append(`<span>总共找到 ${videoSources.length} 个视频。</span><br>`);\n\n                    if (videoSources.length > 0) {\n                        $('#messages').append(`<span>成功提取到视频，找到 ${videoSources.length} 个视频。</span><br>`);\n                        videoSources.forEach((src, idx) => {\n                            $('#messages').append(`<div>视频地址:<span class=\"warn\"> ${src}</span><br></div>`);\n                            $('#video-source-select').append(`<option value=\"${idx}\">视频源 ${idx + 1}</option>`);\n                        });\n                    \n                        if (videoSources.length == 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').hide();\n                            updateVideoSource();\n                        } else if (videoSources.length > 1) {\n                            $('#video-container').show();\n                            $('#video-url').show();\n                            $('#video-source-container').show();\n                            updateVideoSource();\n                        } else {\n                            $('#video-container').hide();\n                            $('#video-url').hide();\n                            $('#video-source-container').hide();\n                        }\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未找到视频源。</span><br>`);\n                        $('#video-container').hide();\n                        $('#video-url').hide();\n                        $('#video-source-container').hide();\n                    }\n\n                    //提取图片\n                    const $imgContents = $(doc).find(config.imgSelector);\n                    const shouldSwap = config.swapImageAttributes;\n                    const newContents = updateImageSrc($imgContents.clone(), shouldSwap);\n                    $('#images').append(newContents).show();\n                    if (newContents.length > 0) {\n                        $('#messages').append(`<span>成功提取图片，共 ${newContents.length} 张。</span><br>`);\n                        newContents.each(function () {\n                            const imgSrc = $(this).attr('src') || $(this).attr('data-original') || $(this).attr('data-src') || $(this).attr('data-url');\n                            $('#messages').append(`<div>地址:<span class=\"warn\"> ${imgSrc}</span><br></div>`);\n                        });\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图片。</span><br>`);\n                    }\n\n                    //提取图片和文本\n                    const textContents = $(doc).find(config.textSelector).map(function () {\n                        const $currentContents = $(this);\n                        $currentContents.find('img + br, script, video, source, iframe').remove();\n                        $currentContents.html($currentContents.html().replace(/>\\s+/gi, '>').replace(/<\\/?br\\s*([^>]*)\\s*\\/?>/gi, '\\n').replace(/\\n+/g, '\\n'));\n                        return $currentContents.html();\n                    }).get().join('');\n                    if (textContents.trim()) {\n                        $('#text').append(`<span>${textContents}</span><br>`).show();\n                        $('#messages').append(`<span>成功提取图文。</span><br>`);\n                    } else {\n                        $('#messages').append(`<span class=\"warn\">未提取到图文。</span><br>`);\n                    }\n\n                    if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                        setTimeout(() => { \n                            canLoadNextPage = true;\n                            loadContent(currentPageIndex + 1); \n                        }, config.delayTime);\n                    } else {\n                        canLoadNextPage = true;\n                        if (autoLoadInProgress) {\n                            hideLoadingStatus();\n                        }\n                    }\n                } catch (parseError) {\n                    $('#messages').append(`<span class=\"error\">解析页面内容时发生错误: ${parseError.message}</span><br>`);\n                    handleLoadFailure(urls, index);\n                } finally {\n                    if (imageBox) imageBox.viewer.update();\n                    if (textBox) textBox.viewer.update();\n                }\n            },\n            error: function (jqXHR, textStatus, errorThrown) {\n                let errorMessage = `内容加载失败: ${urls[index]}`;\n                switch (textStatus) {\n                    case 'timeout':\n                        errorMessage += ', 请求超时';\n                        break;\n                    case 'abort':\n                        errorMessage += ', 请求被取消';\n                        break;\n                    case 'parsererror':\n                        errorMessage += ', 解析响应出错';\n                        break;\n                    default:\n                        errorMessage += `, 状态码: ${jqXHR.status}, 错误信息: ${errorThrown}`;\n                        break;\n                }\n                $('#messages').append(`<span class=\"error\">${errorMessage}</span><br>`);\n                handleLoadFailure(urls, index);\n                }\n            });\n        }\n\n        // 处理加载失败的情况\n        function handleLoadFailure(urls, index) {\n            if (!loadAttempts[urls[index]]) {\n                loadAttempts[urls[index]] = 1;\n            } else {\n                loadAttempts[urls[index]]++;\n            }\n            if (loadAttempts[urls[index]] <= config.maxLoadAttempts) {\n                const retryMessage = `第${index + 1}页加载失败，正在进行第${loadAttempts[urls[index]]}次加载！`;\n                $('#messages').append(`<span class=\"error\">${retryMessage}</span><br>`);\n                setTimeout(() => { \n                    canLoadNextPage = true;\n                    loadContent(index); \n                }, config.retryDelayTime);\n            } else {\n                const finalErrorMessage = `第${index + 1}页加载失败，已达到最大尝试次数(${config.maxLoadAttempts})！`;\n                $('#messages').append(`<span class=\"error\">${finalErrorMessage}</span><br>`);\n                if (autoLoadInProgress && currentPageIndex < urls.length - 1) {\n                    setTimeout(() => { \n                        canLoadNextPage = true;\n                        loadContent(currentPageIndex + 1); \n                    }, config.delayTime);\n                } else {\n                    canLoadNextPage = true;\n                    if (autoLoadInProgress) {\n                        hideLoadingStatus();\n                    }\n                }\n            }\n        }\n\n        // 更新视频源\n        function updateVideoSource() {\n            const selectedIndex = parseInt(document.getElementById('video-source-select').value);\n            if (isNaN(selectedIndex) || !videoSources[selectedIndex]) {\n                $('#messages').append(`<span class=\"warn\">未找到有效的视频源。</span><br>`);\n                console.warn(\"Invalid or undefined video source:\", selectedIndex, videoSources);\n                return;\n            }\n\n            const selectedSource = videoSources[selectedIndex];\n            document.getElementById('video-url').textContent = `视频地址:\\n ${selectedSource}`;\n\n            const videoSourceElement = document.getElementById('video-source');\n            videoSourceElement.src = selectedSource;\n\n            const videoElement = document.getElementById('video-element');\n            videoElement.load();\n\n            $('#messages').append(`<span>更新视频源为: ${selectedSource}</span><br>`);\n            console.log(\"Updated video source to:\", selectedSource);\n        }\n\n        // 切换总页数显示状态\n        function toggleTotalPagesDisplay() {\n            if (urls.length > 1) {\n                $('#page').show();\n            } else {\n                $('#page').hide();\n            }\n        }\n\n        // 页面加载完成后执行的主要逻辑\n        $(document).ready(function () {\n            imageBox = document.getElementById('images');\n            textBox = document.getElementById('text');\n            if (imageBox && textBox) {\n                new Viewer(imageBox, { title: true, interval: 2000 });\n                new Viewer(textBox, { title: true, interval: 2000 });\n            }\n\n            const totalPagesText = config.totalPagesText;\n            const totalPages = parseInt(totalPagesText, 10) || 1;\n            const baseUrl = '{{baseUrl}}';\n\n            clearContainers();\n            $('#urls, #debug-info textarea, #video-url, #video-source-select').empty();\n            $('#urls, #messages, #debug-info, #video-url, #video-container, #video-source-container, #images, #text').hide();\n\n            buildUrls(totalPages, baseUrl);\n\n            const urlSelect = document.getElementById('url-select');\n            if (urlSelect.options.length > 0) {\n                urlSelect.value = '0'; \n\n                if (config.autoLoading) {\n                    autoLoadInProgress = true;\n                    for (let i = 0; i < urls.length; i++) {\n                        loadContent(i);\n                    }\n                } else {\n                    loadContent(0);\n                }\n            } else {\n                loadContent(0);\n            }\n\n            $('#url-select').change(function () {\n                clearContainers();\n                const selectedIndex = parseInt($(this).val());\n                loadContent(selectedIndex);\n            });\n            $('#prev-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex > 0) {\n                    loadContent(currentPageIndex - 1);\n                }\n            });\n            $('#next-page-btn').click(function () {\n                clearContainers();\n                if (currentPageIndex < urls.length - 1) {\n                    loadContent(currentPageIndex + 1);\n                }\n            });\n            $('#auto-load-btn').click(function () {\n                autoLoadInProgress = true;\n                showLoadingStatus(1); \n                for (let i = currentPageIndex + 1; i < urls.length; i++) {\n                    loadContent(i);\n                }\n            });\n            $('#toggle-messages-btn').click(function () { $('#messages').toggle(); });\n            $('#toggle-urls-btn').click(function () { $('#urls').toggle(); });\n            $('#toggle-debug-btn').click(function () { $('#debug-info').toggle(); });\n        });\n    </script>\n</body>\n</html>",
    "ruleImage": "a@data-original",
    "ruleLink": "a.0@href",
    "ruleNextPage": "page||text.下一页@href",
    "rulePubDate": "[class=\"pic-text text-right\"]@text",
    "ruleTitle": "h4@text",
    "singleUrl": false,
    "sortUrl": "搜索🔍::/jiejie/index.php/vod/search.html?wd={{source.getVariable()}}\n黄瓜资源::/jiejie/index.php/vod/type/id/87.html\n155资源::/jiejie/index.php/vod/type/id/248.html\n森林资源::/jiejie/index.php/vod/type/id/117.html\n奥斯卡资源::/jiejie/index.php/vod/type/id/86.html\n百万资源::/jiejie/index.php/vod/type/id/237.html\n制服诱惑::/jiejie/index.php/vod/show/id/251.html\n中文字幕::/jiejie/index.php/vod/show/id/254.html\n美乳巨乳::/jiejie/index.php/vod/show/id/262.html\n熟女人妻::/jiejie/index.php/vod/show/id/259.html\n萝莉少女::/jiejie/index.php/vod/show/id/260.html\n强奸乱伦::/jiejie/index.php/vod/show/id/263.html\n无码专区::/jiejie/index.php/vod/show/id/249.html",
    "sourceComment": "jiejiesp.xyz",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://img4.tuwandata.com/v2/thumb/jpg/NWFkMywxMTI1LDAsOSwzLDEsLTEsTk9ORSwsLDkw/u/res.tuwan.com/zipgoods/20190508/3b6408c569f8eb687a8dd6eb3578bdb9.jpg",
    "sourceName": "6.7",
    "sourceUrl": "https://wap.jiejiesp19.xyz"
  },
  {
    "articleStyle": 1,
    "customOrder": 559,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": false,
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "$.rescont.data",
    "ruleContent": "<video src=\"{{$.rescont.videopath}}\" controls width=\"auto\" height=\"auto\"></video>",
    "ruleImage": "$.coverpath",
    "ruleLink": "http://lu3fcm.aksdsrle.com/api/videoplay/{{$.id}}?&uuid=1",
    "ruleNextPage": "page",
    "rulePubDate": "{{$.authername}}",
    "ruleTitle": "$.title",
    "singleUrl": false,
    "sortUrl": "性感佳人::http://lu3fcm.aksdsrle.com/api/videosort/9?orderby=&page={{page}}&uuid=1&device=0\n国产精品::http://lu3fcm.aksdsrle.com/api/videosort/10?orderby=&page={{page}}&uuid=1&device=0\nH动漫::http://lu3fcm.aksdsrle.com/api/videosort/14?orderby=&page={{page}}&uuid=1&device=0\n欧美激情::http://lu3fcm.aksdsrle.com/api/videosort/16?orderby=&page={{page}}&uuid=1&device=0\n三级电影::http://lu3fcm.aksdsrle.com/api/videosort/25?orderby=&page={{page}}&uuid=1&device=0\n高清无码::http://lu3fcm.aksdsrle.com/api/videosort/26?orderby=&page={{page}}&uuid=1&device=0\n美乳巨乳::http://lu3fcm.aksdsrle.com/api/videosort/27?orderby=&page={{page}}&uuid=1&device=0\n少女萝莉::http://lu3fcm.aksdsrle.com/api/videosort/28?orderby=&page={{page}}&uuid=1&device=0\n家庭乱伦::http://lu3fcm.aksdsrle.com/api/videosort/29?orderby=&page={{page}}&uuid=1&device=0\n绝顶潮吹::http://lu3fcm.aksdsrle.com/api/videosort/30?orderby=&page={{page}}&uuid=1&device=0\n痴女淫乱::http://lu3fcm.aksdsrle.com/api/videosort/31?orderby=&page={{page}}&uuid=1&device=0\n强奸凌辱::http://lu3fcm.aksdsrle.com/api/videosort/34?orderby=&page={{page}}&uuid=1&device=0\n制服丝袜::http://lu3fcm.aksdsrle.com/api/videosort/35?orderby=&page={{page}}&uuid=1&device=0\nAV剧情::http://lu3fcm.aksdsrle.com/api/videosort/36?orderby=&page={{page}}&uuid=1&device=0\n人妻熟女::http://lu3fcm.aksdsrle.com/api/videosort/37?orderby=&page={{page}}&uuid=1&device=0\n偷拍盗摄::http://lu3fcm.aksdsrle.com/api/videosort/38?orderby=&page={{page}}&uuid=1&device=0\n风俗沙龙::http://lu3fcm.aksdsrle.com/api/videosort/39?orderby=&page={{page}}&uuid=1&device=0\n国产传媒::http://lu3fcm.aksdsrle.com/api/videosort/40?orderby=&page={{page}}&uuid=1&device=0\n女同性恋::http://lu3fcm.aksdsrle.com/api/videosort/41?orderby=&page={{page}}&uuid=1&device=0\n直播网红::http://lu3fcm.aksdsrle.com/api/videosort/42?orderby=&page={{page}}&uuid=1&device=0\n国产AV::http://lu3fcm.aksdsrle.com/api/videosort/44?orderby=&page={{page}}&uuid=1&device=0\nSM调教::http://lu3fcm.aksdsrle.com/api/videosort/45?orderby=&page={{page}}&uuid=1&device=0\nAV解说::http://lu3fcm.aksdsrle.com/api/videosort/49?orderby=&page={{page}}&uuid=1&device=0\n热门爆料::http://lu3fcm.aksdsrle.com/api/videosort/50?orderby=&page={{page}}&uuid=1&device=0",
    "sourceGroup": "4视频影视",
    "sourceIcon": "",
    "sourceName": "6.9",
    "sourceUrl": "http://lu3fcm.aksdsrle.com/api/videosort/9?orderby=&page=1&uuid=1&device=0"
  },
  {
    "articleStyle": 2,
    "customOrder": 560,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n  \"User-Agent\": \"Mozilla/5.0 (Linux; Android 13; SM-S918B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36\",\n  \"Referer\": \"https://hksexdoll.com/\"\n}",
    "lastUpdateTime": 0,
    "loadWithBaseUrl": true,
    "ruleArticles": "@js:\n// 1. 列表规则分流\nif (baseUrl.includes(\"hksexdoll.com\")) {\n    // 娃娃：原版规则不动\n    result = org.jsoup.Jsoup.parse(result).select(\".brxe-ivopbr\");\n} else {\n    // 【关键修改】影视：只抓取 class=\"my-movie-grid\" 下面的 li\n    // 这样可以避开 WordPress 顶部的菜单栏干扰\n    result = org.jsoup.Jsoup.parse(result).select(\".my-movie-grid li\");\n}\nresult;",
    "ruleContent": "@js:\n// 5. 详情页跳转逻辑（原版逻辑保持不变）\nif (!baseUrl.includes(\"hksexdoll.com\")) {\n    // 只要不是娃娃官网，直接跳浏览器\n    java.startBrowser(baseUrl, \"正在前往...\");\n    result = \"正在跳转到外部浏览器播放...<br>\" + baseUrl;\n} else {\n    // 娃娃详情页解析（原版代码不动）\n    var doc = org.jsoup.Jsoup.parse(result);\n    var myImgs = [];\n    var rawList = doc.select(\".brxe-image-gallery img, .bricks-image-gallery img, noscript img, .entry-content img\");\n    for (var i = 0; i < rawList.size(); i++) {\n        var s = rawList.get(i).attr(\"data-src\") || rawList.get(i).attr(\"src\");\n        if (s && s.startsWith(\"http\") && !s.toLowerCase().includes(\".svg\") && !s.includes(\"100x100\") && !myImgs.includes(s)) {\n            myImgs.push(s);\n        }\n    }\n    var displayTitle = (typeof title !== 'undefined' && title && title !== \"null\") ? title : (doc.select(\"h1\").text() || \"1:1 Show\");\n    var h = \"<!DOCTYPE html><html><head><style>body{margin:0;background:#000;color:#eee;font-family:sans-serif;padding-bottom:50px} .top{background:#1a1a1a;color:#888;text-align:center;padding:12px;font-size:11px;position:sticky;top:0;z-index:99;letter-spacing:2px;border-bottom:1px solid #222} .header{padding:35px 20px 20px;background:#000;text-align:center} .img-wrap{padding:0 8px} .img-item{position:relative;margin-bottom:10px;border-radius:2px;overflow:hidden} .img-item img{width:100%;display:block;background:#111} .img-count{position:absolute;bottom:8px;right:10px;background:rgba(0,0,0,0.4);color:#999;padding:2px 6px;border-radius:2px;font-size:10px;font-family:monospace}</style></head><body>\";\n    h += \"<div class='top'>HD VISUAL SHOWCASE</div>\";\n    h += \"<div class='header'><h1 style='font-size:19px;margin:0;font-weight:400;color:#fff;letter-spacing:0.5px'>\" + displayTitle + \"</h1></div>\";\n    h += \"<div class='img-wrap'>\";\n    for(var k=0; k<myImgs.length; k++){\n        h += \"<div class='img-item'><img src='\" + myImgs[k] + \"'><span class='img-count'>\" + (k+1) + \" / \" + myImgs.length + \"</span></div>\";\n    }\n    h += \"</div><p style='text-align:center;color:#222;font-size:9px;margin-top:30px;letter-spacing:1px'>EXHIBITION ONLY</p></body></html>\";\n    result = h;\n}\nresult;",
    "ruleImage": "@js:\n// 4. 图片分流\nif (baseUrl.includes(\"hksexdoll.com\")) {\n    // 娃娃：原版规则不动\n    var img = result.select(\"img\").first();\n    result = img ? (img.attr(\"data-src\") || img.attr(\"src\")) : \"\";\n} else {\n    // 【关键修改】影视：抓取你代码里的 Google API 图标\n    var img = result.select(\"img\").first();\n    // 如果抓到了图就用图，抓不到就用默认图标兜底\n    result = img ? img.attr(\"src\") : \"https://goradioai.com/favicon.ico\";\n}\nresult;",
    "ruleLink": "@js:\n// 3. 链接分流\nif (baseUrl.includes(\"hksexdoll.com\")) {\n    var el = result.select(\"a.brxe-sfypzq\").first();\n    result = el ? el.attr(\"href\") : \"\";\n} else {\n    var el = result.select(\"a\").first();\n    result = el ? el.attr(\"href\") : \"\";\n}\nresult;",
    "ruleNextPage": "text.Next@href || .next.page-numbers@href",
    "ruleTitle": "@js:\n// 2. 标题分流\nif (baseUrl.includes(\"hksexdoll.com\")) {\n    result = result.select(\".product-title a\").text();\n} else {\n    // 影视：直接获取文本（会自动忽略掉 img 标签，只留文字）\n    result = result.text();\n}\nresult;",
    "singleUrl": false,
    "sortUrl": "全部展示::/shop/\n🎬 影视大全::https://goradioai.com/share/",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://hksexdoll.com/favicon.ico",
    "sourceName": "7.0",
    "sourceUrl": "https://hksexdoll.com"
  },
  {
    "articleStyle": 2,
    "customOrder": 571,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "header": "{\n\t \"User-Agent\": \"Mozilla/5.0 (Linux; U; Android 9; zh-cn; MIX 2S Build/PKQ1.180729.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36 XiaoMi/MiuiBrowser/16.7.35 swan-mibrowser\",\n\t \"Referer\": \"{{baseUrl}}\"\n}",
    "lastUpdateTime": 1769050738257,
    "loadWithBaseUrl": true,
    "ruleArticles": "li.i_list.list_n2",
    "ruleContent": "<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"UTF-8\">\n<title>{{@@title@text}}</title>\n<style>\nbody {\n    margin: 0;\n    font: 14px/1.4 sans-serif;\n    background: #111;\n    color: #eee;\n}\n\n#msg {\n    position: sticky;\n    top: 0;\n    z-index: 9;\n    background: #222;\n    padding: 8px 12px;\n    text-align: center;\n    font-size: 13px;\n}\n\n#imgList {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: center;\n    padding: 8px;  /* 容器左右边距 */\n    box-sizing: border-box;\n}\n\n#imgList img {\n    display: block;\n    width: 100%;              /* 占满宽度 */\n    max-width: 100%;          /* 防止溢出 */\n    height: auto;\n    min-height: 220px;\n    margin: 6px 0;            /* 只保留上下间距 */\n    border-radius: 4px;\n    background: #222;\n    box-sizing: border-box;\n}\n</style>\n</head>\n<body>\n\n<!-- 实时提示 -->\n<div id=\"msg\">瀑布流初始化完成，向下滚动加载更多~</div>\n\n<!-- 图片容器 -->\n<div id=\"imgList\">\n{{@@class.content_left@img@all}}\n</div>\n\n<script>\n/*** 配置区 ***/\nconst pageUrls = `{{@@class.page@a:not(.current)@href}}`\n  .split('\\n')\n  .map(s => s.trim())\n  .filter(Boolean)\n // .slice(0,2) //选取前三页，测试用\nlet nextIndex = 0;\n\n/*** 页面元素 ***/\nconst imgList = document.getElementById('imgList');\nconst msgBox = document.getElementById('msg');\n\n/*** 工具函数 ***/\nfunction showMsg(text) {\n  if (msgBox) msgBox.textContent = text;\n}\n\n// 使用 iframe 加载\nfunction loadPageInIframe(url) {\n  return new Promise((resolve, reject) => {\n    const iframe = document.createElement('iframe');\n    iframe.style.display = 'none';\n    \n    // 超时处理\n    const timeout = setTimeout(() => {\n      document.body.removeChild(iframe);\n      reject(new Error('请求超时'));\n    }, 10000);\n    \n    iframe.onload = () => {\n      try {\n        clearTimeout(timeout);\n        const doc = iframe.contentDocument;\n        \n        // 查找图片（多重选择器兼容）\n        let imgs = doc.querySelectorAll('.content_left img');\n        if (imgs.length === 0) imgs = doc.querySelectorAll('.content img');\n        if (imgs.length === 0) imgs = doc.querySelectorAll('article img');\n        \n        const urls = Array.from(imgs, img => img.src);\n        \n        document.body.removeChild(iframe);\n        resolve(urls);\n      } catch (e) {\n        document.body.removeChild(iframe);\n        reject(e);\n      }\n    };\n    \n    iframe.onerror = (e) => {\n      clearTimeout(timeout);\n      document.body.removeChild(iframe);\n      reject(new Error('网络错误'));\n    };\n    \n    iframe.src = url;\n    document.body.appendChild(iframe);\n  });\n}\n\n// 使用正则表达式提取（备选方案）\nfunction extractImagesByRegex(html) {\n  const urls = [];\n  // 提取 content_left 区域\n  const areaMatch = html.match(/class=\"content_left\"[\\s\\S]*?<\\/div>/i);\n  const searchHtml = areaMatch ? areaMatch[0] : html;\n  \n  // 提取所有 img src\n  const regex = /<img[^>]+src=[\"']?([^\"'\\s>]+)[\"']?[^>]*>/gi;\n  let match;\n  \n  while ((match = regex.exec(searchHtml)) !== null) {\n    let src = match[1];\n    if (src.startsWith('/')) src = 'https://meirentu.club' + src;\n    if (src.startsWith('http')) urls.push(src);\n  }\n  \n  return urls;\n}\n\n// 获取图片列表（主逻辑）\nasync function getImages(url) {\n  showMsg(`加载中: ${url}`);\n  \n  try {\n    // 方案1：优先使用 iframe（最兼容）\n    return await loadPageInIframe(url);\n  } catch (e1) {\n    showMsg(`iframe失败，尝试正则解析...`);\n    try {\n      // 方案2：降级为 fetch + 正则\n      const resp = await fetch(url);\n      if (!resp.ok) throw new Error(`HTTP ${resp.status}`);\n      const html = await resp.text();\n      return extractImagesByRegex(html);\n    } catch (e2) {\n      throw new Error(`双重失败: ${e2.message}`);\n    }\n  }\n}\n\n// 追加图片\nfunction appendImages(urls) {\n  if (!urls || !urls.length) return;\n  \n  urls.forEach(src => {\n    const img = document.createElement('img');\n    img.src = src;\n    img.style.cssText = 'display:block;width:300px;height:auto;min-height:220px;margin:6px;border-radius:4px;background:#222;';\n    imgList.appendChild(img);\n  });\n}\n\n// 滚动加载\nlet isLoading = false;\nlet retryCount = 0;\nconst maxRetry = 3;\n\nasync function loadMore() {\n  if (isLoading || nextIndex >= pageUrls.length) {\n    if (nextIndex >= pageUrls.length) showMsg('已加载全部');\n    return;\n  }\n  \n  isLoading = true;\n  const url = pageUrls[nextIndex];\n  \n  try {\n    const urls = await getImages(url);\n    \n    if (!urls.length) throw new Error('未找到图片');\n    \n    appendImages(urls);\n    nextIndex++;\n    retryCount = 0; // 重置重试计数\n    \n    showMsg(`已加载 ${nextIndex}/${pageUrls.length} 页`);\n    \n    // 重新监听\n    setTimeout(() => {\n      isLoading = false;\n      observeLast();\n    }, 500);\n    \n  } catch (error) {\n    retryCount++;\n    showMsg(`第${nextIndex + 1}页失败(${retryCount}/${maxRetry}): ${error.message}`);\n    \n    if (retryCount >= maxRetry) {\n      showMsg(`跳过第${nextIndex + 1}页`);\n      nextIndex++;\n      retryCount = 0;\n      // 继续下一页\n      setTimeout(loadMore, 1000);\n    } else {\n      // 重试当前页\n      setTimeout(() => {\n        isLoading = false;\n        loadMore();\n      }, 2000);\n    }\n  }\n}\n\n// IntersectionObserver 监听最后一张图\nlet observer = null;\nfunction observeLast() {\n  if (observer) observer.disconnect();\n  \n  const imgs = imgList.querySelectorAll('img');\n  if (!imgs.length) return;\n  \n  const lastImg = imgs[imgs.length - 1];\n  \n  observer = new IntersectionObserver((entries) => {\n    if (entries[0].isIntersecting && !isLoading) {\n      observer.disconnect();\n      loadMore();\n    }\n  }, {\n    rootMargin: '800px',\n    threshold: 0.01\n  });\n  \n  observer.observe(lastImg);\n}\n\n// 初始化\nshowMsg(`初始化完成，共${pageUrls.length}页待加载`);\nsetTimeout(observeLast, 1000); // 延迟确保图片渲染完成\n\n</script>\n</body>\n</html>",
    "ruleImage": "img@data-src##$##,{\"headers\":{\n\t \"User-Agent\": \"Mozilla/5.0 (Linux; U; Android 9; zh-cn; MIX 2S Build/PKQ1.180729.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36 XiaoMi/MiuiBrowser/16.7.35 swan-mibrowser\",\n\t \"Referer\": \"{{baseUrl}}\"\n}}",
    "ruleLink": "a.0@href",
    "ruleNextPage": "text.下页@href",
    "rulePubDate": "##(\\d{4}-\\d{2}-\\d{2})##$1###",
    "ruleTitle": ".meta-title@text",
    "singleUrl": false,
    "sortUrl": "XiuRen秀人网::/group/XiuRen-1.html\nMFStar模范学院::/group/MFStar-1.html\nMiStar魅妍社::/group/MiStar-1.html\nMyGirl美媛馆::/group/MyGirl-1.html\nImiss爱蜜社::/group/Imiss-1.html\nBoLoli兔几盟::/group/BoLoli-1.html\nYouWu尤物馆::/group/YouWu-1.html\nUxing优星馆::/group/Uxing-1.html\nMiiTao蜜桃社::/group/MiiTao-1.html\nFeiLin嗲囡囡::/group/FeiLin-1.html\nWingS影私荟::/group/WingS-1.html\nTaste顽味生活::/group/Taste-1.html\nLeYuan星乐园::/group/LeYuan-1.html\nHuaYan花の颜::/group/HuaYan-1.html\nDKGirl御女郎::/group/DKGirl-1.html\nMintYe薄荷叶::/group/MintYe-1.html\nYouMi尤蜜荟::/group/YouMi-1.html\nCandy糖果画报::/group/Candy-1.html\nMTMeng模特联盟::/group/MTMeng-1.html\nMicat猫萌榜::/group/Micat-1.html\nHuaYang花漾::/group/HuaYang-1.html\nXingYan星颜社::/group/XingYan-1.html\nXiaoYu画语界::/group/XiaoYu-1.html",
    "sourceGroup": "5图片杂志",
    "sourceIcon": "https://meirentu.club/static/img/logo.png",
    "sourceName": "7.9",
    "sourceUrl": "https://meirentu.club",
    "style": "#imgList img {\n    width: 100% !important;\n    max-width: 100% !important;\n    height: auto !important;\n}"
  },
  {
    "articleStyle": 3,
    "customOrder": 578,
    "enableJs": true,
    "enabled": true,
    "enabledCookieJar": true,
    "lastUpdateTime": 1774110092242,
    "loadWithBaseUrl": true,
    "ruleArticles": ".item-box",
    "ruleContent": "<js>\n// 提取m3u8链接\nvar m3u8Match = result.match(/\"([^\"]*?index\\.m3u8[^\"]*)\"/i) \n             || result.match(/'([^']*?index\\.m3u8[^']*)'/i);\n\nvar p = '';\nif (m3u8Match) {\n    var u = m3u8Match[1]\n        .replace(/\\\\\\//g, '/')      // \\/ → /\n        .replace(/\\\\\\\\/g, '\\\\')      // \\\\ → \\\n        .trim();\n    \n    // 补全协议\n    if (u.startsWith('//')) {\n        u = 'https:' + u;\n    } else if (!u.startsWith('http')) {\n        // 需要基础URL，这里假设当前页面URL在result中或需要传入\n        u = 'https://' + u;  // 简化处理，或根据实际需求调整\n    }\n    p = u;\n}\n\n// 标题：从 span.tx-flex-sh > a 的 title 属性获取\nvar t = java.getString('.tags-box.0@a.0 @text') || '未知标题';\n\n// 标签：从 meta[name=\"description\"] 的 content 获取  \nvar b = java.getString('.mb5.1 @text') || '';\nvar updateIndex = b.indexOf('更新时间');\nif (updateIndex !== -1) {\nvar d = b.substring(updateIndex);  // 保留\"更新时间\"及之后的内容\n}\n\n`<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>${t}</title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\nbody{font-family:-apple-system,sans-serif;background:#f0f9ff;padding:10px}\n.v-box{max-width:800px;margin:0 auto;background:white;border-radius:12px;box-shadow:0 5px 15px rgba(0,0,0,0.1);overflow:hidden}\n.header{padding:12px;border-bottom:1px solid #eee;display:flex;flex-wrap:wrap;justify-content:space-between}\n.title{font-size:18px;font-weight:600;margin-bottom:8px;width:100%}\n.tags{color:#5f6368;font-size:14px;flex:1;min-width:60%;word-break:break-all}\n.time{color:#5f6368;font-size:14px;text-align:right;flex-basis:35%}\n.v-wrap{position:relative;padding-top:56.25%;background:#000}\n.video{position:absolute;top:0;left:0;width:100%;height:100%}\n.footer{padding:8px;text-align:center;color:#5f6368;font-size:13px}\n.info-box{padding:15px;font-size:14px;line-height:1.6}\n.info-box p{margin:8px 0}\n.hint{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,0.7);color:#fff;padding:12px 20px;border-radius:20px;font-size:1.1rem;z-index:10;display:none}\n.controls{position:absolute;top:0;left:0;width:100%;height:4px;background:rgba(255,255,255,0.3);z-index:5;transition:opacity 0.3s}\n.progress{height:100%;background:#4a9eff;width:0}\n</style>\n</head>\n<body>\n<div class=\"v-box\">\n<div class=\"header\">\n<div class=\"title\">${t}</div>\n<div class=\"tags\">${d}</div>\n<div class=\"time\" id=\"timeDisplay\">00:00/00:00</div></div>\n<div class=\"v-wrap\">\n<div class=\"controls\"><div class=\"progress\" id=\"progressBar\"></div></div>\n<div class=\"hint\" id=\"hint\">快进中 &gt;&gt;</div>\n<video class=\"video\" id=\"v\" controls playsinline>\n<source src=\"${p}\" type=\"application/x-mpegURL\">您的浏览器不支持HTML5视频\n</video>\n</div>\n<div class=\"footer\">滑动调整进度 | 长按2倍速</div>\n</div>\n<script>\nvar v = document.getElementById('v');\nvar tDisplay = document.getElementById('timeDisplay');\nvar pBar = document.getElementById('progressBar');\nvar hint = document.getElementById('hint');\nvar startX = 0, startTime = 0;\nvar longPressTimer;\nvar sensitivity = 0.1;\nvar longPressTime = 500;\nvar hintDuration = 2000;\nfunction updateTime() {\nif (!v.duration) return;\nvar m1 = Math.floor(v.currentTime / 60);\nvar s1 = Math.floor(v.currentTime % 60);\nvar m2 = Math.floor(v.duration / 60);\nvar s2 = Math.floor(v.duration % 60);\ntDisplay.textContent = m1 + ':' + (s1 < 10 ? '0' : '') + s1 + '/' + m2 + ':' + (s2 < 10 ? '0' : '') + s2;\npBar.style.width = (v.currentTime / v.duration) * 100 + '%';}\nv.addEventListener('timeupdate', updateTime);\nv.addEventListener('loadedmetadata', updateTime);\nv.addEventListener('touchstart', function(e) {\nstartX = e.touches[0].clientX;\nstartTime = Date.now();\nif (longPressTimer) clearTimeout(longPressTimer);\nhint.style.display = 'none';\nlongPressTimer = setTimeout(function() {\nv.playbackRate = 2.0;\nhint.style.display = 'block';\nsetTimeout(function() { hint.style.display = 'none'; }, hintDuration);}, longPressTime);});\nv.addEventListener('touchmove', function(e) {\ne.preventDefault();\nclearTimeout(longPressTimer);\nvar diffX = e.touches[0].clientX - startX;\nvar change = diffX * sensitivity * v.duration / 100;\nv.currentTime = Math.max(0, Math.min(v.currentTime + change, v.duration));\nstartX = e.touches[0].clientX;updateTime();});\nv.addEventListener('touchend', function() {\nv.playbackRate = 1.0;\nclearTimeout(longPressTimer);});\n</script>\n</body>\n</html>`\n</js>\n",
    "ruleImage": "img@src",
    "ruleLink": "a@href<js> resutl='https://l5--25w3xh.wumatantoupai1.com'+result</js><js>\nresult=result.replace('oddetail', '');\n</js>\n",
    "ruleNextPage": ".laypage_next@href",
    "ruleTitle": "a@title",
    "shouldOverrideUrlLoading": "ture",
    "singleUrl": false,
    "sortUrl": "搜索::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key={{source.getVariable()}}\n国产传媒::https://l5--25w3xh.wumatantoupai1.com/t/2/\n网红头条::https://l5--25w3xh.wumatantoupai1.com/t/241/\n国产视频::https://l5--25w3xh.wumatantoupai1.com/t/163/\n探花系列::https://l5--25w3xh.wumatantoupai1.com/t/239/\n网暴黑料::https://l5--25w3xh.wumatantoupai1.com/t/232/\n自拍::https://l5--25w3xh.wumatantoupai1.com/s/wd/%E5%9B%BD%E4%BA%A7%E8%87%AA%E6%8B%8D\nIPX::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=IPX\nJUL::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=JUL\nABW::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=ABW\nJUQ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=JUQ\nSONE::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=SONE\nMIRD::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=MIRD\nIPZZ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=IPZZ\nOFJE::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=OFJE\nMIDV::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=MIDV\nCAWD::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=CAWD\nSONE::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=SONE\nMIAB::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=MIAB\nMIMK::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=MIMK\nSSIS::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=SSIS\nPRED::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=PRED\nDASS::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=DASS\nSTARS::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=STARS\nFSDSS::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=FSDSS\nSTART::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=START\nmiru::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=miru\n爆菊::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=爆菊\n求饶::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=求饶\n短裙::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=短裙\n浴场::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=浴场\n迷晕::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=迷晕\n嫖妓::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=嫖妓\n正妹::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=正妹\n紧身::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=紧身\n老婆::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=老婆\n中出::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=中出\n女模::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=女模\n按摩::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=按摩\n阴道::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=阴道\n开档::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=开档\n拍摄::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=拍摄\n海滩::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=海滩\n奴隶::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=奴隶\n惩罚::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=惩罚\n精液::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=精液\n嫂子::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=嫂子\n上位::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=上位\n秘书::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=秘书\n上班::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=上班\n强迫::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=强迫\n甜蜜::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=甜蜜\n温柔::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=温柔\n暴力::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=暴力\n撕烂::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=撕烂\n女星::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=女星\n卖淫::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=卖淫\n夜班::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=夜班\n尾随::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=尾随\n色狼::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=色狼\n痴汉::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=痴汉\n偶遇::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=偶遇\n巨乳::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=巨乳\n调教::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=调教\n萝莉::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=萝莉\n自慰::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=自慰\n妈妈::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=妈妈\n母子::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=母子\n石川澪::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=石川澪\n皆月光::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=皆月光\n大槻響::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=大槻響\n櫻空桃::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=櫻空桃\n波多野結衣::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=波多野結衣\n桃乃木香奈::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=桃乃木香奈\n七瀨愛麗絲::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=七瀨愛麗絲\n吉根柚莉愛::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=吉根柚莉愛\n柏木こなつ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=柏木こなつ\n天馬ゆい::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=天馬ゆい\n夢乃あいか::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=夢乃あいか\n未步なな::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=未步なな\n倉本すみれ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=倉本すみれ\n望月つぼみ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=望月つぼみ\n新井リマ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=新井リマ\n浅野こころ::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=浅野こころ\n東雲みれい::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=東雲みれい\n松本一香::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=松本一香\n木下日葵::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=木下日葵\n瀬户环奈::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=瀬户环奈\n河北彩花::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=河北彩花\n沙月惠奈::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=沙月惠奈\n美園和花::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=美園和花\n沙月芽衣::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=沙月芽衣\n藤森里穗::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=藤森里穗\n石原希望::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=石原希望\n月乃露娜::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=月乃露娜\n小宵虎南::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=小宵虎南\n七澤米亞::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=七澤米亞\n小野六花::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=小野六花\n彌生美月::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=彌生美月\n山岸逢花::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=山岸逢花\n三上悠亞::https://l5--25w3xh.wumatantoupai1.com/addons/s/wd/link.php?key=三上悠亞",
    "sourceComment": "┍   　  　书源作者：闻君三月　　  　┒\n├───┬────────────┤\n│！免责│本书源只提供代码进行技术│\n│！声明│交流，请于２４小时后删除│\n└────────────────┘",
    "sourceGroup": "4视频影视",
    "sourceIcon": "https://bike-egg-cup.img12345.com/ico/heiseicon.png",
    "sourceName": "8.4",
    "sourceUrl": "https://l5--25w3xh.wumatantoupai1.com/show/2/ "
  }
]