From 9a7b2f74ea62ac79ef9bb6eb2941214d4e34dae1 Mon Sep 17 00:00:00 2001 From: hjdhnx <49803097+hjdhnx@users.noreply.github.com> Date: Wed, 14 Jan 2026 00:28:34 +0800 Subject: [PATCH 01/99] Delete jx/_30wmv.js --- jx/_30wmv.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 jx/_30wmv.js diff --git a/jx/_30wmv.js b/jx/_30wmv.js deleted file mode 100644 index 1df6a6a3..00000000 --- a/jx/_30wmv.js +++ /dev/null @@ -1 +0,0 @@ -H4sIAAAAAAAAA81X61MTVxT/nr/immHcRMNuEqBgGKYDkWoRjMNjWqd2YNncJAub3XUfwYiZQVuZtghDW6yvitJKdUYN2tYHiPDHNLuBT/4LPXcfeWxiq/VL98Nm995zfuf1uydnGQaV722Vdhb2nnxVXnkwNjz4Zvumj2FQRtPkGMMIEscKGUnVYh2dHZ2MzCoqZsbbwjPZ3Me6IvQ4YjhLRyNJLUdzUpZRJTGtMpFwOHykrT0SprPTOR+BNDa2jcvrx0eHBvc2XphPLxkv1o3LL3ycJKoamk1j7biWFQqoB7XQCj6r8woOUDQzLvCT1jtWNXpKpYKOQpLV2BM4D+LUiejZtmk9PtA/gM9FhnPTSvbY2OftI+LoZyfxoKzIVLePOXTIhw6hvfu/mqvLxo0H+5cXy6+Lxsbm3tM1smEUb5Y2vy1tzTuu3fuztLtmXtyAPcYxOHUObM36EFwZzCaxEnPeyEWNqVhp7U1jUaNi6FR8fKw3hJpckIbS613I9Kl4+eFGVakKNIxTWMEKoFBOckk+6WxelTSJ5jiqArRX3IEYzNvr5tby/tqz/du/vNm+Yj5YMxfulF4tGcXr5k+b5Yc3ypc294q7+9eKlo1CyFfo9vl8rJoXOZTSRU7jJREJ7Pl8gBdlXQshKDKbVYNOdGCIxC8JmBakdICyhGJUCFkPwW5LyHqG9Fi/dJbVuEzA5sEZJnAmeTjIBL+IfNn97oACtisMmAMjiZO0qim8mOZT+QA7w/IawiKn5GUtMDHrF/XsJFb8sZZZC6BQmAg6IJqSrykRgZRkEq1aKaR72QVVY57lxspS0jSpCtNGd9FhKtQoHZdEEVs5JdInMJZbewU+h5vJ9nIclrXWfpGTkhAdUUif5+VmojlW4CEfEuGFnYHKSiDY3A0NPG4dzcuY4LKyLPAcS/xipqAw3YjLkLOs9ehaqrWLqkMo1ANmsZaRkgAiQx/wOEdqFLPu9etElNiOIV1M4hQv4mS9gMZnsQR1Rx3QJyo7he66cimYlMqOF1pAoPmJYIQ8J0lkjeEEHqJmch2WCANNQ8kz0KeAXU7pgw0Woi7HrObm8CuJbX7BPvQ0K5fQhGSB5aAp+QGOooLBGiwgtYI1XRG9dJ21UGMoHELgR8wySFv5qnaRf6JYoVBjxTEx+x+R7AaAOHI8UQAHa9iuZRRpBol4BvUrCuGUbbTgKzS0Cvfo2aancR5Obs7FajxyIG636TjRkgZGaFihx7RUl5NwQEAXLrj93FMfkE3IWuOBldkkOTKxKiqs0KemObXTQ14piWukyCvdH+9rxjg+hQJ8Dh08CPHQUMBsIIgO9PSQUnusO17RIP32uCAp3U21iA+1epZP8b54VbrgzcEwVnVBq1Xq7bcM1lTCTnTINdNImwoOrUkjFkErZW7KCUdN1AXh7WxwD4rjC04e/XdakEQfqFPwJrjBdGNWwPAH8Aq0/4e8crx6T165Wu/LK9Brzqu31NTOeMi110iwCmCVYA1BfDjjYFAc4dMiC6L4E15khYAqhlCW5ULWn4qqsVm5ZniJwEBrLmybS+vG0h3j/oJ59Ym5WPxr7uL+4xXzj6vwajy+Zvxwxbi1BUNg+dayMbft6u7Pvdrb+R4Aho52gBV0mJiBe8UOPPtbI+0fHenobG+PdPjJ+9DpkcRoYrwvkRj69OQxf9ACs0dI0FLZNI5AwidaZlWx0DILgHCvABZq0OqBJrprgDKsmonUlo046KIH6863G0sUwjCezJcfPSq9nNu//twsPiu/+tFc/bn0csnOHgRozC+aj9acdH1319iYb5oK27ybDVVsEmPUjtGSrIQJETthOJVu5n+03v9GAtRMPk3bi+1HtUY9CPiLaVGaCQQbWl9VAcKHMyl2hgeHpk53puJsV6Ivnug6TXkFSdQgGe4N9x7tix7pikfbKSfPLudoVF65Y36zXH68Yywveg0BeytjzTuxuR49SiNz9ev9ubvWrIGAvuVHv5Ve/u4xQxpfYnKqocX5Adwfs0zUrxO/YIP8eHesde9qxT/YrDx7NTWITAUBv6rDtKuq/mYdsuowFKdx5Hci8aShjUbQrJBNU2Pz+d7uinFr1dtL6j8XHBMwvs1IU7w+qadZSdVFcF5MC0ArFeaoPKtLmCcjXu2aKMCa60Hz7uV+1WBrgvL32zYJY1MsL+BkzA9/zjW0885c/kHyse3Sm+jBK6cLbA2GvzqY/Q2jRI9Yuw8AAA== \ No newline at end of file From 6dbe3cf2f5843467a6742e413e1ce759a911d99a Mon Sep 17 00:00:00 2001 From: Taois Date: Wed, 14 Jan 2026 00:35:33 +0800 Subject: [PATCH 02/99] =?UTF-8?q?feat:=E8=B0=83=E6=95=B4=E6=89=93=E5=8C=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.js | 2 +- package.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.js b/package.js index 0ba76628..1e52492e 100644 --- a/package.js +++ b/package.js @@ -7,7 +7,7 @@ import url from 'url'; const EXCLUDE_DIRS = ['.git', '.idea', 'soft', 'examples', 'apps/cat', 'plugins/pvideo', 'plugins/req-proxy', 'plugins/pup-sniffer', 'plugins/mediaProxy', 'pyTools', 'drop_code', 'jstest', 'local', 'logs', '对话1.txt', 'vod_cache', 'data/mv']; // 要排除的文件列表 -const EXCLUDE_FILES = ['config/env.json', '.env', '.claude', 'clipboard.txt', 'clipboard.txt.bak', '.plugins.js', 'yarn.lock', 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', 'json/UC分享.json', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json']; +const EXCLUDE_FILES = ['config/env.json', '.env', '.claude', 'clipboard.txt', 'clipboard.txt.bak', '.plugins.js', 'yarn.lock', 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', 'json/UC分享.json', 'jx/_30wmv.js', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json']; // 获取脚本所在目录 const getScriptDir = () => dirname(resolve(url.fileURLToPath(import.meta.url))); diff --git a/package.py b/package.py index 3067cbcb..827deca9 100644 --- a/package.py +++ b/package.py @@ -17,7 +17,8 @@ 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', 'json/UC分享.json', - 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json'] + 'jx/_30wmv.js', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', + 'custom.json'] def get_script_dir(): From feff76dcaa5b0a61cc632be5de663cd8beb1439e Mon Sep 17 00:00:00 2001 From: Taois Date: Wed, 14 Jan 2026 00:36:06 +0800 Subject: [PATCH 03/99] =?UTF-8?q?feat:=E8=B0=83=E6=95=B4=E6=89=93=E5=8C=85?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 78c5d859..41e6c6cd 100644 --- a/.gitignore +++ b/.gitignore @@ -159,3 +159,4 @@ dist /scripts/mjs/index.db /scripts/test/rsa-test.json /apps/salary/ +/jx/_30wmv.js From 0e640432499a7e160da69da5cc6f30d146d85901 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 14:43:27 +0800 Subject: [PATCH 04/99] =?UTF-8?q?=E5=88=A0=E9=99=A4=20Mac=20=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84=20.DS=5FStore=20=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spider/.DS_Store | Bin 10244 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 spider/.DS_Store diff --git a/spider/.DS_Store b/spider/.DS_Store deleted file mode 100644 index 76d54f9f61d5a408cc902a2d2bb657bfa67634b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHMO>Epm6n<~JBj3PM-E&-;>v*wl{l3*WAE1X?n)?vHjo)<<~`56XZwAA zKRdGkfW__V1po~Ia@09hkI~Sh@paz2S|*yw6GhSou)&;nSjBXh*(EI}BmxoviGV~v zA|Mes2nbNk<}EiAQaMTlBmxqF4gx$sXw*5?Biah7NF6kYEdbFhO^Zf6?E{347EwK- zt&j>;x@Wk1z(^INEe3|_w61Y+qIyJIAq~|5Lv_ID$r$ZWP&}RVG$9VChg6Od0f|62 z0(|d202MGGfDcpqcOFXbP=EWGXhOLyy8{fWvAsT*{W>M9KovZat3#QdK=NQEHSmp; zMh5PIpOX2smyFr)>(MF06SMBvelRidBW8|dUl|x2R0f9zZ7HGZ|s zm}9ni!@Ol%jj}p+jk$qgyOt*u?5af~>mS)}l{JcN+pYRSw-hcYN=_-Or<={$*{N}D z>f-d?xYnGToEX<;CMWmylw7`W{_;}!zO&`BPw2g=VU)07IK1wR+%93SUD=6j!SCC) z{H&^xH96(z(6QlHkEBl-!b4z4Lr(dACk7W6vkVz25UI%U!E^c6DK6!?%K!7{6LpkNXvm zInE;U?Z9U4>bg$=&j;4lyt~2Zi8}=DLY*)9w=B;m+NHCyYIvUE)~w?0ZO1SzXTdG9 zAYfZulHZLCS@bM^C-Ll3-Kf}Zt#I}C5W<4K*k;}e85Ig415nT(pA~#=tUVP`Ty~jj zDM~^AAeza+IdbzGP=ZZpz-RCUd<9S7JNOBHgQu9qllUf{!)d&NSMhzkiAz|)O|Nt-#a1HOG@wa?G@uB;~ z051@e$%LQbandUWgzWz-282l|XpTndL99`lVBn Date: Wed, 14 Jan 2026 18:41:51 +0800 Subject: [PATCH 05/99] =?UTF-8?q?=E6=B8=85=E7=90=86=E6=9C=AA=E8=B7=9F?= =?UTF-8?q?=E8=B8=AA=E6=96=87=E4=BB=B6=E5=92=8C=E5=88=A0=E9=99=A4=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\351\237\251\345\211\247\347\275\221.js" | 124 ------------------ 1 file changed, 124 deletions(-) delete mode 100755 "spider/catvod/\351\237\251\345\211\247\347\275\221.js" diff --git "a/spider/catvod/\351\237\251\345\211\247\347\275\221.js" "b/spider/catvod/\351\237\251\345\211\247\347\275\221.js" deleted file mode 100755 index e09b7dcd..00000000 --- "a/spider/catvod/\351\237\251\345\211\247\347\275\221.js" +++ /dev/null @@ -1,124 +0,0 @@ -/* -@header({ - searchable: 1, - filterable: 1, - quickSearch: 1, - title: '韩剧网', - lang: 'cat' -}) -*/ - -let host = 'https://hanju51.com'; -let headers = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", - "Referer": host + "/" -}; - -function extractVideos(html, limit = 0) { - let videos = []; - let liPattern = /
  • ([^<]+)<\/a>/) || [])[1] || ""; - let vod_pic = (item.match(/data-original="([^"]+)"/) || [])[1] || ""; - let vod_remarks = (item.match(/\s*]*>\.\.\.<\/a>/)?.[1] ? parseInt(html.match(/\/(\d+)\/<\/a>\s*]*>\.\.\.<\/a>/)[1]) : 999; - - return JSON.stringify({ list, page: parseInt(pg || 1), pagecount, limit: 20 }); -} - -async function detail(id) { - let html = (await req(`${host}/voddetail/${id}/`, { headers })).content || ''; - if (!html) return JSON.stringify({ list: [] }); - - // 提取线路名称 - let sources = [...html.matchAll(/]*class="fed-tabs-btn[^"]*"[^>]*>([^<]+)<\/a>/g)].map(m => m[1].trim()); - // 提取对应的集数区块 - let blocks = [...html.matchAll(/
      ]*>([^<]+)<\/a>/g)]; - if (eps.length) { - playFrom.push(sources[i]); - playUrl.push(eps.map(e => e[2].trim() + '$' + e[1].trim()).join('#')); - } - } - - // 无有效线路则返回空(已移除回退逻辑) - if (playFrom.length === 0) return JSON.stringify({ list: [] }); - - // 基本信息 - let vod_name = pdfh(html, "h1&&Text") || ""; - let vod_pic = (html.match(/data-original="([^"]+)"/) || [])[1] || ""; - if (vod_pic && !vod_pic.startsWith('http')) vod_pic = host + vod_pic; - let vod_content = (html.match(/

      { - let m = html.match(new RegExp(`${label}:([\\s\\S]*?)<\\/li>`)); - return m ? [...m[1].matchAll(/]*>([^<]+)<\/a>/g)].map(x => x[1]).join(" / ") : ""; - }; - - return JSON.stringify({ - list: [{ - vod_id: id, - vod_name, - vod_pic, - vod_content, - vod_year, - vod_director: extract("导演"), - vod_actor: extract("主演"), - vod_play_from: playFrom.join('$$$'), - vod_play_url: playUrl.join('$$$') - }] - }); -} - -async function play(flag, id, flags) { - return JSON.stringify({ - parse: 1, - url: `${host}/vodplay/${id}/`, - header: headers - }); -} - -export default { home, category, detail, play }; \ No newline at end of file From b9d7614f2a08f0454892276b6b7bca08bf98b176 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 19:31:49 +0800 Subject: [PATCH 06/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=92=8C=E7=A7=BB=E5=8A=A8=E6=99=A8=E6=9B=A6?= =?UTF-8?q?=E7=88=AC=E8=99=AB=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 15 --------------- config/parses.conf | 3 +++ .../\345\205\211\351\200\237[\344\274\230].js" | 0 3 files changed, 3 insertions(+), 15 deletions(-) rename "spider/js/\345\205\211\351\200\237[\344\274\230].js" => "spider/js_bad/\345\205\211\351\200\237[\344\274\230].js" (100%) diff --git a/config/map.txt b/config/map.txt index 07d40beb..756117df 100644 --- a/config/map.txt +++ b/config/map.txt @@ -31,20 +31,13 @@ UC分享@@?type=url¶ms=../json/UC分享.json@@UC分享[盘] 网盘[模板]@@?type=url¶ms=../json/域名配置.json$至臻@@至臻ᵐ[盘] AppFox@@http://app.hktvyb.cc@@TVB云播[AFX] AppFox@@{"host":"https://cunchu8.obs.cn-north-4.myhuaweicloud.com/config.json","parse":{"JL4K":"http://194.147.100.155:7891/?url="}}@@火猫影视[AFX] -AppFox@@{"host":"http://kumiao.yzbao.com.cn","parse":{"qq|qiyi|mgtv|youku|bilibili":"https://api.qljson.xyz/api/?key=67f6a108dc6d84eaf81ac58417c1f72a&url="}}@@未来影视[AFX] AppFei@@https://ysc.yy-fun.cc/feiapp@@呀哩4K[AF] AppFei@@https://ysa.yy-fun.cc/feiapp@@森林动漫[AF] AppGet@@{"host":"https://api1.bffree.cn","key":"2015692015692015"}@@橘子[AG¹] AppGet@@{"host":"https://dy.58ys.vip","key":"JEWibY1AgWF0V1xx"}@@五八[AG¹] AppGet@@{"host":"https://mac.555618.xyz","key":"#getapp@TMD@2025"}@@玲珑[AG¹] -AppGet@@{"host":"http://154.12.90.59:14500","key":"J6AIORKJ3PQOJKM3"}@@火猫[AG¹] -AppGet@@{"host":"http://www.milkidc.cn","key":"20c79c979da8db0f"}@@米诺-旧[AG¹] -AppGet@@{"host":"http://new.tkbot.fun","key":"d032c12876bc6848"}@@米兔-旧[AG¹] AppGet@@{"host":"https://app.omofun1.top","key":"66dc309cbeeca454"}@@OMOfun[AG¹] AppGet@@{"host":"http://tv.yy-fun.cc","key":"qkxnwkfjwpcnwycl"}@@丫丫动漫[AG¹] -AppGet@@{"host":"https://newappcms.cs4k.top","key":"Z98KXaLtO2wC1Pte","path":"/api.php/qijiappapi"}@@仓鼠[AG²] -AppGet@@{"host":"https://lanyinghz.oss-cn-hangzhou.aliyuncs.com/lanyingxmy.txt","key":"ca94b06ca359d80e","path":"/api.php/qijiappapi"}@@雄鹰[AG²] -AppMuou@@{"host":"https://muouapp.oss-cn-hangzhou.aliyuncs.com/MUOUAPP/764119293.txt","version":"4.2.0"}@@23影视[AM] AppSk@@{"host":"https://skyappdata-1321528676.cos.accelerate.myqcloud.com/4kapp/appipr.txt","key":"ygcnbckhcuvygdyb","iv":"4023892775143708"}@@即看影视[AS] AppSk@@{"host":"https://kankelm.cn:2024/appdomain.txt","key":"ygcnbcvybqqckwqy","iv":"1583560747143708"}@@看客联盟[AS] AppSk@@{"host":"https://dmsk.oss-rg-china-mainland.aliyuncs.com/dmapp/dmapi.txt","key":"ygcnbcobcegtgigg","iv":"4058263969143708"}@@2k动漫[AS] @@ -52,27 +45,19 @@ AppSk@@{"host":"https://sk.xiaoyaoys.top/skkkkkkk.txt","key":"ygcnbcczduwydmrs", AppV6@@{"api":"http://yjyi.juyongjiu.com/icciu_api.php/v1.vod","datasignkey":"6QQNUsP3PkD2ajJCPCY8","apisignkey":"lvdoutv-1.0.0"}@@剧永久[AV⁶] AppV6@@http://jxfmax.juxiafan.com/icciu_api.php/v1.vod@@剧下饭[AV⁶] AppToV5@@http://118.89.203.120:8762@@番喜[ATV⁵] -AppToV5@@http://118.89.203.120:8366@@畅看[ATV⁵] AppToV5@@http://111.173.114.61:8762@@爱看剧Fax[ATV⁵] AppToV5@@http://38.55.237.41:8762@@皮皮虾[ATV⁵] -AppV2²@@https://dmz8k4.wiki@@大米[AV²] AppV2²@@https://www.heli888.cc@@河狸![AV²] AppV2²@@http://38.47.213.61:41271@@闪影[AV²] -AppV2²@@https://www.rebovod.com@@热剧[AV²] AppV2²@@http://v.lnhaozhenjin.cn@@好震惊[AV²] AppV2²@@http://jxfmax.juxiafan.com@@剧下饭[AV²] AppV1@@http://ziyuncms.feifan12.xyz/api.php@@紫云[AV¹] getapp3.4.4@@{"host":"https://jingyu4k-1312635929.cos.ap-nanjing.myqcloud.com/1.json","datakey":"AAdgrdghjfgswerA","api":2}@@鲸鱼影视[AG³] -getapp3.4.4@@{"host":"https://staraugust123456.oss-cn-hangzhou.aliyuncs.com/1.txt","datakey":"staraugust123456","api":2}@@云云[AG³] -getapp3.4.4@@{"host":"http://tengxunyunaliyun.oss-cn-shanghai.aliyuncs.com/tengxunyun.txt","datakey":"n3l2tx5jdkp9s2c8"}@@白蛇[AG³] -getapp3.4.4@@{"host":"http://appcms.4kdq.icu","key":"R6FVRw4jsy4Hsitj"}@@4K大全[AG³] getapp3.4.4@@{"host":"https://www.guahd.com/1.txt","key":"f2A7D4B9E8C16531"}@@瓜萌[AG³] -getapp3.4.4@@{"host":"https://apiapplbys.lbys.app:5678","key":"apiapplbyskey168"}@@萝卜[AG³] getapp3.4.4@@{"host":"https://99.jl8.top/1.txt","key":"xnybssspqtwotuwj"}@@七月[AG³] getapp3.4.4@@{"host":"http://tvb.yy-fun.cc","key":"jcTz6Jda2aKrH8Tk"}@@掌上追剧[AG³] AppHs@@{"host":"https://dy.jmzp.net.cn","app_id":"shiguang","deviceid":"","versionCode":"10000","UMENG_CHANNEL":"guan"}@@拾光视频[Hs] AppHs@@{"host":"https://dy.jszdzs.com","app_id":"xuebao","deviceid":"","versionCode":"21300","UMENG_CHANNEL":"share"}@@雪豹视频[Hs] -AppHs@@{"host":"https://dy.stxbed.com","app_id":"haigou","deviceid":"","versionCode":"20100","UMENG_CHANNEL":"zhuan"}@@海狗视频[Hs] AppYqk@@{"host":"https://gapi0320.3njzmrx1.com/config.json,https://gapi0320.lq0okex8.com/config.json,https://gapi0320.zabqs8xp.com/config.json,https://yappconfig-20250628-1318635097.cos.ap-shanghai.myqcloud.com/config.json,https://yconfig-20250628-1360051343.cos.ap-guangzhou.myqcloud.com/config.json","appId":"d6d520ea90904f1ba680ed6c9c9f9007","appkey":"70af67d2b6cf47679b397ea4c1886877","udid":"bfc18c00-c866-46cb-8d7b-121c39b942d4","bundlerId":"com.flotimingo.ts","source":"1001_default","version":"1.3.10","versionCode":1104}@@一起看[Ayq] AppYqk@@{"host":"https://gapi0725.5p8jcjc.com/config.json,https://gapi0725.olrv5gz.com/config.json,https://gapi0725.mvljeat.com/config.json,https://jzapp-1318635097.cos.ap-shanghai.myqcloud.com/config.json,https://juzi-config-1360051343.cos.ap-shanghai.myqcloud.com/config.json","appId":"fea23e11fc1241409682880e15fb2851","appkey":"f384b87cc9ef41e4842dda977bae2c7f","udid":"bfc18c00-c866-46cb-8d7b-121c39b942d4","bundlerId":"com.voraguzzee.ts","source":"1003_default","version":"1.0.1","versionCode":1000}@@橘子TV[Ayq] php@@{"host":"https://www.baidu.com"}@@php测试 diff --git a/config/parses.conf b/config/parses.conf index 245dda4b..f150792d 100644 --- a/config/parses.conf +++ b/config/parses.conf @@ -12,6 +12,9 @@ HGvip,http://1.94.221.189:88/algorithm.php?url=,1 # J皮皮虾,http://45.207.215.101:5423/index.php?url=,1 # WEB解析放后面 +W花旗,https://www.huaqi.live/?url= +W冰豆,https://bd.jx.cn/?url= +W盘古,https://www.playm3u8.cn/jiexi.php?url= # W虾米,https://jx.xmflv.com/?url= # W无双,http://103.117.123.193:1980/players/?url= W1,https://jx.xymp4.cc/?url= diff --git "a/spider/js/\345\205\211\351\200\237[\344\274\230].js" "b/spider/js_bad/\345\205\211\351\200\237[\344\274\230].js" similarity index 100% rename from "spider/js/\345\205\211\351\200\237[\344\274\230].js" rename to "spider/js_bad/\345\205\211\351\200\237[\344\274\230].js" From 6b6d8e624a3ee58747109d787dd0496671597fc8 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 19:43:29 +0800 Subject: [PATCH 07/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=88=AC=E8=99=AB?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\212\250\346\274\253[\346\274\253].js" | 314 ++++++++++++++++++ ...\345\212\250\346\274\253[\346\274\253].js" | 0 2 files changed, 314 insertions(+) create mode 100644 "spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" rename "spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253.js" => "spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" (100%) diff --git "a/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" "b/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" new file mode 100644 index 00000000..e11949df --- /dev/null +++ "b/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" @@ -0,0 +1,314 @@ +/* +title: '嗷呜动漫', author: '小可乐/v6.1.1' +说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下 +"ext": { + "host": "xxxx", //站点网址 + "timeout": 6000 //请求超时,单位毫秒 +} +*/ +import {Crypto} from 'assets://js/lib/cat.js'; + +const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36'; +const DefHeader = {'User-Agent': MOBILE_UA}; +var HOST; +var KParams = { + headers: {'User-Agent': MOBILE_UA}, + timeout: 5000 +}; + +async function init(cfg) { + try { + HOST = (cfg.ext?.host?.trim() || 'https://www.aowu.tv').replace(/\/$/, ''); + KParams.headers['Referer'] = HOST; + let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10); + KParams.timeout = parseTimeout > 0 ? parseTimeout : 5000; + } catch (e) { + console.error('初始化参数失败:', e.message); + } +} + +async function home(filter) { + try { + let kclassName = '新番$20&番剧$21&剧场$22'; + let classes = kclassName.split('&').map(item => { + let [cName, cId] = item.split('$'); + return {type_name: cName, type_id: cId}; + }); + let filters = {}; + try { + const nameObj = { class: 'class,剧情', year: 'year,年份', by: 'by,排序' }; + const flValues = { class: ['搞笑','恋爱','校园','后宫','治愈','日常','原创','战斗','百合','BL','卖肉','漫画改','游戏改','异世界','泡面番','轻小说改','OVA','OAD','京阿尼','芳文社','A-1Pictures','CloverWorks','J.C.STAFF','动画工房','SUNRISE','Production.I.G','MADHouse','BONES','P.A.WORKS','SHAFT','MAPPA','ufotable','TRIGGER','WITSTUDIO'], year: ['2026','2025','2024','2023','2022','2021','2020','2019','2018','2017','2016','2015','2014','2013','2012','2011','2010','2009','2008','2007','2006','2005','2004','2003','2002','2001','2000','1999','1998','1997','1996','1995','1994','1993','1992','1991','1990'], by: ['按最新,time', '按最热,hits', '按评分,score'] }; + for (let item of classes) { + filters[item.type_id] = Object.entries(nameObj).map(([nObjk, nObjv]) => { + let [kkey, kname] = nObjv.split(','); + let fvalue = flValues[nObjk] || []; + if (item.type_id === '20' && nObjk === 'year') {fvalue = fvalue.slice(0, 2);} + let kvalue = fvalue.map(it => { + let [n, v] = [it, it]; + if (nObjk === 'by') {[n, v] = it.split(',');} + return {n: n, v: v}; + }); + if (nObjk !== 'by') {kvalue.unshift({n: '全部', v: ''});} + return {key: kkey, name: kname, value: kvalue}; + }).filter(flt => flt.key && flt.value.length > 1); + } + } catch (e) { + filters = {}; + } + return JSON.stringify({class: classes, filters: filters}); + } catch (e) { + console.error('获取分类失败:', e.message); + return JSON.stringify({class: [], filters: {}}); + } +} + +async function homeVod() { + try { + let homeUrl = HOST; + let resHtml = await request(homeUrl); + let VODS = getVodList(resHtml, true); + return JSON.stringify({list: VODS}); + } catch (e) { + console.error('推荐页获取失败:', e.message); + return JSON.stringify({list: []}); + } +} + +async function category(tid, pg, filter, extend) { + try { + pg = parseInt(pg, 10); + pg = pg > 0 ? pg : 1; + let cateBody = `type=${tid}&class=${extend?.class ?? ''}&year=${extend?.year ?? ''}&by=${extend?.by ?? ''}&page=${pg}`; + let cateUrl = `${HOST}/index.php/ds_api/vod`; + let resObj = safeParseJSON(await request(cateUrl, { + headers: {...KParams.headers, 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'}, + method: 'POST', + body: cateBody + })); + if (!resObj) {throw new Error('源码对象为空');} + let VODS = []; + let listArr = Array.isArray(resObj.list) ? resObj.list : []; + for (let it of listArr) { + let kname = it.vod_name || '名称'; + let kpic = it.vod_pic || '图片'; + let kremarks = `${it.vod_remarks || '状态'}|${it.vod_douban_score || '无评分'}`; + let kyear = extend?.year || ''; + let kid = it.url ?? 'Id'; + VODS.push({ + vod_name: kname, + vod_pic: kpic, + vod_remarks: kremarks, + vod_year: kyear, + vod_id: `${kid}@${kname}@${kpic}@${kremarks}` + }); + } + let {pagecount=1000, limit=30, total=30000} = resObj; + return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: 30, total: total}); + } catch (e) { + console.error('类别页获取失败:', e.message); + return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0}); + } +} + +async function search(wd, quick, pg) { + try { + pg = parseInt(pg, 10); + pg = pg > 0 ? pg : 1; + let searchUrl = `${HOST}/search/${wd}----------${pg}---.html`; + let resHtml = await request(searchUrl); + let VODS = getVodList(resHtml); + return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300}); + } catch (e) { + console.error('搜索页获取失败:', e.message); + return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0}); + } +} + +function getVodList(khtml, rec = false) { + try { + if (!khtml) {throw new Error('源码为空');} + let kvods = []; + let selector = rec ? '.public-list-box' : '.search-list'; + let listArr = pdfa(khtml, selector); + for (let it of listArr) { + let kname = cutStr(it, 'alt="', '"', '名称'); + let kpic = cutStr(it, 'data-src="', '"', '图片'); + let kremarks = rec ? `${cutStr(it, 'public-prt£>', '<', '类型')}|${cutStr(it, 'ft2">', '<', '状态')}` : cutStr(it, 'this-wap">', '', '状态'); + let kid = cutStr(it, 'href="', '"', 'Id'); + kvods.push({ + vod_name: kname, + vod_pic: kpic, + vod_remarks: kremarks, + vod_id: `${kid}@${kname}@${kpic}@${kremarks}` + }); + } + return kvods; + } catch (e) { + console.error(`生成视频列表失败:`, e.message); + return []; + } +} + +async function detail(ids) { + try { + let [id, kname, kpic, kremarks] = ids.split('@'); + let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id; + let resHtml = await request(detailUrl); + if (!resHtml) {throw new Error('源码为空');} + let intros = cutStr(resHtml, 'search-show', '

    ', '', false); + let ktabs = pdfa(resHtml, '.anthology-tab&&a').map((it,idx) => cutStr(it, '', '<', `线路${idx+1}`)); + let kurls = pdfa(resHtml, '.anthology-list-play').map(item => { + return pdfa(item, 'a').map(it => { return `${cutStr(it, '>', '<', 'noEpi')}$${cutStr(it, 'href="', '"', 'noUrl')}` }).join('#'); + }); + let VOD = { + vod_id: detailUrl, + vod_name: kname, + vod_pic: kpic, + type_name: cutStr(intros, '类型:', '
  • ', '类型'), + vod_remarks: `${cutStr(intros, '状态:', '', '状态')}|${cutStr(intros, '更新:', '', '更新')}`, + vod_year: cutStr(intros, '年份:', '', '1000'), + vod_area: cutStr(intros, '地区:', '', '地区'), + vod_lang: cutStr(intros, '语言:', '', '语言'), + vod_director: cutStr(intros, '导演:', '', '').replace(/,$/, '') || '导演', + vod_actor: cutStr(intros, '主演:', '', '').replace(/,$/, '') || '主演', + vod_content: cutStr(intros, '简介:', '', '') || kname, + vod_play_from: ktabs.join('$$$'), + vod_play_url: kurls.join('$$$') + }; + return JSON.stringify({list: [VOD]}); + } catch (e) { + console.error('详情页获取失败:', e.message); + return JSON.stringify({list: []}); + } +} + +async function play(flag, ids, flags) { + try { + let playUrl = !/^http/.test(ids) ? `${HOST}${ids}` : ids; + let kp = 0, kurl = ''; + let resHtml = await request(playUrl); + let codeObj = safeParseJSON(cutStr(resHtml, 'var player_£=', '<', '', false)); + let jurl = codeObj?.url ?? ''; + jurl = safeUrlDecode(safeB64Decode(jurl)); + if (jurl) { + jurl = `${HOST}/player/?url=${jurl}&next=`; + resHtml = await request(jurl); + let encryptedUrl = cutStr(resHtml, 'const encryptedUrl = "', '"', ''); + let sessionKey = cutStr(resHtml, 'const sessionKey = "', '"', ''); + kurl = urlAesDecrypt(encryptedUrl, sessionKey); + } + if (!/^http/.test(kurl)) { + kurl = playUrl; + kp = 1; + } + return JSON.stringify({jx: 0, parse: kp, url: kurl, header: DefHeader}); + } catch (e) { + console.error('播放失败:', e.message); + return JSON.stringify({jx: 0, parse: 0, url: '', header: {}}); + } +} + +function urlAesDecrypt(ciphertext, key) { + try { + const rawData = Crypto.enc.Base64.parse(ciphertext); + const keyWordArr = Crypto.enc.Utf8.parse(key); + const ivWordArr = Crypto.lib.WordArray.create(rawData.words.slice(0, 4)); + const encrypted = Crypto.lib.WordArray.create(rawData.words.slice(4)); + const decrypted = Crypto.AES.decrypt( { ciphertext: encrypted }, keyWordArr, + { + iv: ivWordArr, + mode: Crypto.mode.CBC, + padding: Crypto.pad.Pkcs7 + } + ); + return decrypted.toString(Crypto.enc.Utf8); + } catch (e) { + return ''; + } +} + +function safeB64Decode(b64Str) { + try {return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(b64Str));} catch (e) {return '';} +} + +function safeUrlDecode(urlStr) { + try {return decodeURIComponent(urlStr);} catch (e) {return '';} +} + +function safeParseJSON(jStr) { + try {return JSON.parse(jStr);} catch (e) {return null;} +} + +function cutStr(str, prefix = '', suffix = '', defaultVal = 'cutFaile', clean = true, i = 1, all = false) { + try { + if (typeof str !== 'string' || !str) {throw new Error('被截取对象需为非空字符串');} + const cleanStr = cs => String(cs).replace(/<[^>]*?>/g, ' ').replace(/( |\u00A0|\s)+/g, ' ').trim().replace(/\s+/g, ' '); + const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&'); + let pre = esc(prefix).replace(/£/g, '[^]*?'), end = esc(suffix); + let regex = new RegExp(`${pre ? pre : '^'}([^]*?)${end ? end : '$'}`, 'g'); + let matchIterator = str.matchAll(regex); + if (all) { + let matchArr = [...matchIterator]; + return matchArr.length ? matchArr.map(it => { + const val = it[1] ?? defaultVal; + return clean && val !== defaultVal ? cleanStr(val) : val; + }) : [defaultVal]; + } + i = parseInt(i, 10); + if (isNaN(i) || i < 1) {throw new Error('序号必须为正整数');} + let tgIdx = i - 1,matchIdx = 0; + for (const match of matchIterator) { + if (matchIdx++ === tgIdx) { + const result = match[1] ?? defaultVal; + return clean && result !== defaultVal ? cleanStr(result) : result; + } + } + return defaultVal; + } catch (e) { + console.error(`字符串截取失败:`, e.message); + return all ? ['cutErr'] : 'cutErr'; + } +} + +async function request(reqUrl, options = {}) { + try { + if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); } + if (typeof options !== 'object' || Array.isArray(options) || options === null) { throw new Error('options类型需为非null对象'); } + options.method = options.method?.toUpperCase() || 'GET'; + if (['GET', 'HEAD'].includes(options.method)) { + delete options.body; + delete options.data; + delete options.postType; + } + let {headers, timeout, buffer, ...restOpts} = options; + const optObj = { + headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers, + timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout, + buffer: buffer ?? 0, + ...restOpts + }; + const res = await req(reqUrl, optObj); + if (options.withHeaders) { + const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {}; + const resWithHeaders = { ...resHeaders, body: res?.content ?? '' }; + return JSON.stringify(resWithHeaders); + } + return res?.content ?? ''; + } catch (e) { + console.error(`${reqUrl}→请求失败:`, e.message); + return options?.withHeaders ? JSON.stringify({ body: '' }) : ''; + } +} + +export function __jsEvalReturn() { + return { + init, + home, + homeVod, + category, + search, + detail, + play, + proxy: null + }; +} \ No newline at end of file diff --git "a/spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253.js" "b/spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" similarity index 100% rename from "spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253.js" rename to "spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" From 7d385c87508f71621868dfda543949fe9101c118 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 19:43:29 +0800 Subject: [PATCH 08/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=88=AC=E8=99=AB?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\351\237\263\344\271\220[\345\220\254].js" | 42 +++ ...45\207\244\345\207\260FM[\345\220\254].js" | 8 +- ...\345\220\254\344\271\246[\345\220\254].js" | 7 + ...\351\237\263\344\271\220[\345\220\254].js" | 43 +++ ...50\234\273\350\234\223FM[\345\220\254].js" | 44 +++ ...\351\237\263\344\271\220[\345\220\254].py" | 261 ++++++++++++++++++ ...\351\237\263\344\271\220[\345\220\254].py" | 259 +++++++++++++++++ 7 files changed, 659 insertions(+), 5 deletions(-) create mode 100644 "spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" create mode 100644 "spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" create mode 100644 "spider/js/\350\234\273\350\234\223FM[\345\220\254].js" create mode 100644 "spider/py/\347\210\261\345\220\254\351\237\263\344\271\220[\345\220\254].py" create mode 100644 "spider/py/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].py" diff --git "a/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" new file mode 100644 index 00000000..8b7f56e7 --- /dev/null +++ "b/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" @@ -0,0 +1,42 @@ +/* +@header({ + searchable: 2, + filterable: 0, + quickSearch: 0, + title: 'DJ音乐', + author: 'EylinSir', + '类型': '影视', + logo: 'https://pic.289.com/up/2023-12/20231219154340126.png', + lang: 'ds' +}) +*/ + +var rule = { + title:'DJ音乐', + host:'http://www.djuu.com', + homeUrl:'/exclusive/115_1.html', + url:'/djlist/fyclass_fypage.html', + searchUrl:'/search?musicname=**', + author: 'EylinSir', + logo: 'https://pic.289.com/up/2023-12/20231219154340126.png', + hikerListCol: 'icon_4', + searchable:2, + quickSearch:0, + class_name: '迪高串烧&慢摇串烧&慢歌串烧&中文Remix&外文Remix&HOUSE&HOUSE&霓虹风格&Mashup&中文DISCO&外文DISCO', + class_url: '1&2&3&4&5&6&7&8&9&10', + headers:{ + 'User-Agent':'PC_UA' + }, + timeout:5000, + limit:6, + double:false, + play_parse:true, + lazy: async function() { + let {input} = this; + return input; + }, + 推荐:'*', + 一级:'.list_musiclist tr:gt(0);a&&title;img&&src;.cor999:eq(1)&&Text;a&&href', + 二级:'*', + 搜索:'*;*;*;.sc_1&&Text;*', +} diff --git "a/spider/js/\345\207\244\345\207\260FM[\345\220\254].js" "b/spider/js/\345\207\244\345\207\260FM[\345\220\254].js" index 30528bf1..b18b4cd7 100644 --- "a/spider/js/\345\207\244\345\207\260FM[\345\220\254].js" +++ "b/spider/js/\345\207\244\345\207\260FM[\345\220\254].js" @@ -108,10 +108,8 @@ var rule = { }); return setResult(d); }, - lazy: async function () { - return { - parse: 0, - url: input - }; + lazy: async function() { + let {input} = this; + return input; }, } \ No newline at end of file diff --git "a/spider/js/\345\215\232\347\234\213\345\220\254\344\271\246[\345\220\254].js" "b/spider/js/\345\215\232\347\234\213\345\220\254\344\271\246[\345\220\254].js" index daf7fdfc..f65a0999 100644 --- "a/spider/js/\345\215\232\347\234\213\345\220\254\344\271\246[\345\220\254].js" +++ "b/spider/js/\345\215\232\347\234\213\345\220\254\344\271\246[\345\220\254].js" @@ -17,11 +17,18 @@ var rule = { url: '/voice/book/list?instance_id=25304&page=fypage&category_id=fyclass&num=24', detailUrl: '/voice/album/units?album_id=fyid&page=1&num=200&order=1', searchUrl: 'https://es.bookan.com.cn/api/v3/voice/book?instanceId=25304&keyword=**&pageNum=fypage&limitNum=20', + author: 'EylinSir', + logo: 'https://pp.myapp.com/ma_icon/0/icon_52647879_1746000007/256', + hikerListCol: 'icon_4', searchable: 2, quickSearch: 0, class_name: '少年读物&儿童文学&国学经典&文艺少年&育儿心经&心理哲学&青春励志&历史小说&故事会&音乐戏剧&相声评书', class_url: '1305&1304&1320&1306&1309&1310&1307&1312&1303&1317&1319', headers: {'User-Agent': 'MOBILE_UA'}, + lazy: async function() { + let {input} = this; + return input; + }, 推荐: '*', 一级: 'json:data.list;name;cover;extra.author;id', 二级: async function () { diff --git "a/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" new file mode 100644 index 00000000..766d76fe --- /dev/null +++ "b/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" @@ -0,0 +1,43 @@ +/* +@header({ + searchable: 2, + filterable: 0, + quickSearch: 0, + title: '种子音乐[听]', + '类型': '影视', + lang: 'ds' +}) +*/ + +var rule = { + title: '种子音乐[听]', + host: 'https://www.zz123.com', + homeUrl: '/list/mszm.htm?page=1', + url: '/fyclass.htm?page=fypage', + searchUrl: '/ajax/?act=search&key=**&lang=', + detailUrl: '/play/fyid.html', + author: 'EylinSir', + limit: 6, + searchable: 2, + quickSearch: 0, + headers: { + 'User-Agent': 'MOBILE_UA', + 'referer': 'https://www.zz123.com/', + }, + class_parse: '.aside-menu-list.channel&&[href*=list];a&&Text;a&&href;.(list.*).htm', + play_parse: true, + sniffer:1, + isVideo:"http((?!http).){26,}\\.(m3u8|mp4|flv|avi|mkv|wmv|mpg|mpeg|mov|ts|3gp|rm|rmvb|asf|m4a|mp3|wma)", + lazy: async function(flag, id) { + let url = id.replace(/play\/(\w+)\.htm/, 'ajax/?act=songinfo&id=$1&lang='); + let data = JSON.parse(await request(url, { + headers: rule.headers + })); + let mp3 = data.data.mp3; + return {parse: 0, url: mp3, header: rule.headers}; + }, + 推荐: "*", + 一级: '.mobile-list&&.mobile-list-item;.songname&&Text;.lazyload&&data-src;.authorname&&Text;a&&href', + 二级: '*', + 搜索: 'json:data;mname;pic;sname;id', +} \ No newline at end of file diff --git "a/spider/js/\350\234\273\350\234\223FM[\345\220\254].js" "b/spider/js/\350\234\273\350\234\223FM[\345\220\254].js" new file mode 100644 index 00000000..1c12888b --- /dev/null +++ "b/spider/js/\350\234\273\350\234\223FM[\345\220\254].js" @@ -0,0 +1,44 @@ +/* +@header({ + searchable: 0, + filterable: 0, + quickSearch: 0, + title: '蜻蜓FM', + '类型': '影视', + lang: 'ds' +}) +*/ + +var rule = { + title:'蜻蜓FM', + host:'http://www.qingting.fm', + url:'/radiopage/fyclass/fypage', + author: 'EylinSir', + logo: 'https://sss.qtfm.cn/images/qingting_icon_new.png', + hikerListCol: 'icon_4', + searchUrl:'', + searchable:0, + quickSearch:0, + class_name:'广东&浙江&北京&天津&河北&上海&山西&内蒙古&辽宁&吉林&黑龙江&江苏&安徽&福建&江西&山东&河南&湖北&湖南&广西&海南&重庆&四川&贵州&云南&陕西&甘肃&宁夏&新疆&西藏&青海&资讯&音乐&交通&经济&文艺&都市&体育&双语&综合&生活&旅游&曲艺&方言', + class_url:'217&99&3&5&7&83&19&31&44&59&69&85&111&129&139&151&169&187&202&239&254&257&259&281&291&316&327&351&357&308&342&433&442&429&439&432&441&430&431&440&438&435&436&434', + headers:{ + 'User-Agent':'PC_UA' + }, + timeout:5000, + play_parse:true, + play_json:0, + lazy: async function(flag, id) { + return id.replace("www.qingting.fm/radios/", "lhttp.qingting.fm/live/") + "/64k.mp3"; + }, + limit:6, + double:false, + //推荐:'*', + 一级:'.contentSec&&.radio;span&&Text;img&&src;.descRadio&&Text;a&&href', + 二级:'*', + 搜索:'', + + //是否启用辅助嗅探: 1,0 + sniffer:1, + // 辅助嗅探规则 + isVideo:"http((?!http).){26,}\\.(m3u8|mp4|flv|avi|mkv|wmv|mpg|mpeg|mov|ts|3gp|rm|rmvb|asf|m4a|mp3|wma)", +} \ No newline at end of file diff --git "a/spider/py/\347\210\261\345\220\254\351\237\263\344\271\220[\345\220\254].py" "b/spider/py/\347\210\261\345\220\254\351\237\263\344\271\220[\345\220\254].py" new file mode 100644 index 00000000..de2bf071 --- /dev/null +++ "b/spider/py/\347\210\261\345\220\254\351\237\263\344\271\220[\345\220\254].py" @@ -0,0 +1,261 @@ +""" +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '爱听音乐', + lang: 'hipy' +}) +""" + +import re +import sys +from base64 import b64encode, b64decode +from urllib.parse import quote +from pyquery import PyQuery as pq +from requests import Session, adapters +from urllib3.util.retry import Retry +from concurrent.futures import ThreadPoolExecutor, as_completed +sys.path.append('..') +from base.spider import Spider + +class Spider(Spider): + def init(self, extend=""): + self.host = "http://www.2t58.com" + self.session = Session() + # 重试策略(保留原逻辑) + retries = Retry(total=2, backoff_factor=0.5, status_forcelist=[429, 500, 502, 503, 504]) + adapter = adapters.HTTPAdapter(max_retries=retries, pool_connections=20, pool_maxsize=50) + self.session.mount("http://", adapter) + self.session.mount("https://", adapter) + self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"} + self.session.headers.update(self.headers) + + # 基础方法(保留原逻辑) + def getName(self): return "爱听音乐" + def isVideoFormat(self, url): return bool(re.search(r'\.(m3u8|mp4|mp3|m4a|flv)(\?|$)', url or "", re.I)) + def manualVideoCheck(self): return False + def destroy(self): self.session.close() + + def homeContent(self, filter): + classes = [ + {"type_name": "电台", "type_id": "/radiolist/index.html"}, + {"type_name": "歌单", "type_id": "/playtype/index.html"}, + {"type_name": "专辑", "type_id": "/albumlist/index.html"}, + {"type_name": "歌手", "type_id": "/singerlist/index/index/index/index.html"}, + {"type_name": "高清MV", "type_id": "/mvlist/oumei.html"}, + {"type_name": "新歌榜", "type_id": "/list/new.html"}, + {"type_name": "TOP榜单", "type_id": "/list/top.html"} + ] + filters = {} + + fetch_targets = ["/list/new.html", "/list/top.html", "/mvlist/index.html", "/playtype/index.html", "/albumlist/index.html", "/radiolist/index.html"] + for path in fetch_targets: + if f_data := self._fetch_filters(path): + filters[path] = f_data + + if "/radiolist/index.html" not in filters: + filters["/radiolist/index.html"] = [ + {"key": "id", "name": "分类", "value": [ + {"n": "最新", "v": "index"}, {"n": "最热", "v": "hot"}, {"n": "有声小说", "v": "novel"}, + {"n": "相声", "v": "xiangyi"}, {"n": "音乐", "v": "music"}, {"n": "情感", "v": "emotion"}, + {"n": "国漫", "v": "game"}, {"n": "影视", "v": "yingshi"}, {"n": "脱口秀", "v": "talkshow"}, + {"n": "历史", "v": "history"}, {"n": "儿童", "v": "children"}, {"n": "教育", "v": "education"}, + {"n": "八卦", "v": "gossip"}, {"n": "推理", "v": "tuili"}, {"n": "头条", "v": "headline"} + ]} + ] + + filters["/singerlist/index/index/index/index.html"] = [ + {"key": "area", "name": "地区", "value": [{"n": "全部", "v": "index"}, {"n": "华语", "v": "huayu"}, {"n": "欧美", "v": "oumei"}, {"n": "韩国", "v": "hanguo"}, {"n": "日本", "v": "ribrn"}]}, + {"key": "sex", "name": "性别", "value": [{"n": "全部", "v": "index"}, {"n": "男", "v": "male"}, {"n": "女", "v": "girl"}, {"n": "组合", "v": "band"}]}, + {"key": "genre", "name": "流派", "value": [{"n": n, "v": v} for n, v in [("全部","index"),("流行","liuxing"),("电子","dianzi"),("摇滚","yaogun"),("嘻哈","xiha"),("R&B","rb"),("民谣","minyao"),("爵士","jueshi"),("古典","gudian")]]}, + {"key": "char", "name": "字母", "value": [{"n": "全部", "v": "index"}] + [{"n": chr(i), "v": chr(i).lower()} for i in range(65, 91)]} + ] + return {"class": classes, "filters": filters, "list": []} + + def homeVideoContent(self): return {"list": []} + + def categoryContent(self, tid, pg, filter, extend): + pg = int(pg or 1) + url = tid + if "/singerlist/" in tid: + p = tid.split('/') + if len(p) >= 6: + p[2], p[3], p[4] = extend.get("area", p[2]), extend.get("sex", p[3]), extend.get("genre", p[4]) + p[-1] = f"{extend.get('char', 'index')}.html" + url = "/".join(p) + elif "id" in extend and extend["id"] not in ["index", "top"]: + url = tid.replace("index.html", f"{extend['id']}.html").replace("top.html", f"{extend['id']}.html") + if url == tid: url = f"{tid.rsplit('/', 1)[0]}/{extend['id']}.html" + + if pg > 1: + url = re.sub(r'/\d+\.html$', '.html', url) + url = re.sub(r'_\d+\.html$', '.html', url) + + if "/singerlist/" in url or "/radiolist/" in url or "/mvlist/" in url or "/playtype/" in url or "/list/" in url: + url = url.replace(".html", f"/{pg}.html") + else: + url = url.replace(".html", f"_{pg}.html") + + doc = self.getpq(url) + items = doc(".play_list li, .video_list li, .pic_list li, .singer_list li, .ali li, .layui-row li") or doc(".base_l li") + return {"list": self._parse_list(items, tid), "page": pg, "pagecount": 9999, "limit": 90, "total": 999999} + + def searchContent(self, key, quick, pg="1"): + return {"list": self._parse_list(self.getpq(f"/so/{quote(key)}/{pg}.html")(".base_l li, .play_list li"), "search"), "page": int(pg)} + + def detailContent(self, ids): + url = self._abs(ids[0]) + doc = self.getpq(url) + title = self._clean(doc("h1").text() or doc("title").text() or "") + pic = self._abs(doc(".djpg img, .pic img, .djpic img").attr("src")) + vod = {"vod_id": url, "vod_name": title, "vod_pic": pic, "vod_play_from": "爱听音乐", "vod_content": ""} + + if any(x in url for x in ["/playlist/", "/album/", "/list/", "/singer/", "/special/", "/radio/", "/radiolist/"]): + eps = self._get_eps(doc) + page_urls = set() + for a in doc(".page a, .dede_pages a, .pagelist a").items(): + href = a.attr("href") + if href and not href.startswith("javascript") and href != "#": + abs_url = self._abs(href) + if abs_url != url: + page_urls.add(abs_url) + + if page_urls: + sorted_urls = sorted(list(page_urls), key=lambda x: int(re.search(r'[_\/](\d+)\.html', x).group(1)) if re.search(r'[_\/](\d+)\.html', x) else 0) + with ThreadPoolExecutor(max_workers=5) as executor: + futures = [executor.submit(self._fetch_eps, u) for u in sorted_urls] + for f in futures: + try: + if more_eps := f.result(): + eps.extend(more_eps) + except: pass + + if eps: + vod["vod_play_from"], vod["vod_play_url"] = "播放列表", "#".join(eps) + return {"list": [vod]} + + play_list = [] + if mid := re.search(r'/(song|mp3|radio|radiolist|radioplay)/([^/]+)\.html', url): + sid = mid.group(2) + if pu := self._api("/js/play.php", data={"id": sid, "type": "music"}, method="POST", referer=url): + play_list.append(f"播放${self.e64('0@@@@'+pu)}") + lrc = f"{self.host}/plug/down.php?ac=music&lk=lrc&id={sid}" + play_list.append(f"歌词${self.e64('0@@@@'+lrc)}") + + elif vid := re.search(r'/(video|mp4)/([^/]+)\.html', url): + tasks = [] + with ThreadPoolExecutor(max_workers=3) as executor: + futures = {executor.submit(self._api, "/plug/down.php", None, {"ac": "vplay", "id": vid.group(2), "q": q}, "GET", url): n for n, q in [("蓝光", 1080), ("超清", 720), ("高清", 480)]} + for f in as_completed(futures): + if u := f.result(): + name = futures[f] + play_list.append(f"{name}${self.e64('0@@@@'+u)}") + play_list.sort(key=lambda x: {"蓝":0, "超":1, "高":2}.get(x[0], 3)) + + vod["vod_play_url"] = "#".join(play_list) if play_list else f"解析失败${self.e64('1@@@@'+url)}" + return {"list": [vod]} + + def _fetch_eps(self, url): + return self._get_eps(self.getpq(url)) + + def _get_eps(self, doc): + local_eps = [] + for li in doc(".play_list li, .song_list li, .music_list li").items(): + href = li("a").attr("href") + if not href or not re.search(r'/(song|mp3|radio|radiolist|radioplay)/', href): continue + song_name = self._clean(li("a").eq(0).text() or li(".name").text()) + local_eps.append(f"{song_name}${self.e64('1@@@@'+self._abs(href))}") + return local_eps + + def playerContent(self, flag, id, vipFlags): + url = self.d64(id).split("@@@@")[-1].replace(r"\/", "/") + if ".html" in url and not self.isVideoFormat(url): + if mid := re.search(r'/(song|mp3|radio|radiolist|radioplay)/([^/]+)\.html', url): + url = self._api("/js/play.php", data={"id": mid.group(2), "type": "music"}, method="POST", referer=url) or url + + elif vid := re.search(r'/(video|mp4)/([^/]+)\.html', url): + with ThreadPoolExecutor(max_workers=3) as executor: + futures = [executor.submit(self._api, "/plug/down.php", None, {"ac": "vplay", "id": vid.group(2), "q": q}, "GET", url) for q in [1080, 720, 480]] + for f in as_completed(futures): + if v_url := f.result(): + url = v_url + executor.shutdown(wait=False) + break + return {"parse": 0, "url": url, "header": {"User-Agent": self.headers["User-Agent"]}} + + def localProxy(self, param): + if param.get("type") == "img": + try: + r = self.session.get(param["url"], headers={"Referer": "https://www.2t58.com/"}, timeout=5) + if r.status_code == 200: return [200, r.headers.get("Content-Type", "image/jpeg"), r.content, {}] + except: pass + return None + + def _parse_list(self, items, tid=""): + res = [] + for li in items.items(): + a = li("a").eq(0) + href = a.attr("href") + if not href or href == "/" or any(x in href for x in ["/user/", "/login/", "javascript"]): continue + name = self._clean(li(".name").text() or a.attr("title") or a.text()) + if not name: continue + + img = li("img").attr("src") or "" + if img: + img = self._abs(img.replace('120', '500')) + pic = f"{self.getProxyUrl()}&url={img}&type=img" + else: pic = "" + + url = self._abs(href) + is_singer = "/singerlist/" in tid and "/singer/" in url + style = {"type": "oval"} if is_singer else ({"type": "list"} if any(x in tid for x in ["/list/", "/playtype/", "/albumlist/"]) else {"type": "rect", "ratio": 1.33}) + res.append({"vod_id": url, "vod_name": name, "vod_pic": pic, "vod_tag": "", "style": style}) + return res + + def _clean(self, text): + return re.sub(r'(爱听音乐网|视频下载说明|视频下载地址|www\.2t58\.com|MP3免费下载|LRC歌词下载|全部歌曲|\[第\d+页\]|刷新|每日推荐|最新|热门|推荐|MV|高清|无损)', '', text, flags=re.I).strip() + + def _fetch_filters(self, url): + doc = self.getpq(url) + selectors = [".ilingku_fl", ".class_list", ".screen_list", ".box_list", ".nav_list"] + if not (groups := [doc(s) for s in selectors if doc(s)]): return [] + + filters = [] + for i, group in enumerate(groups): + opts = [{"n": "全部", "v": "top" if "top" in url else "index"}] + seen = {opts[0]['v']} + for a in group("a").items(): + href = a.attr("href") + if not href: continue + v = href.split("?")[0].rstrip('/').split('/')[-1].replace('.html','') + if v not in seen: + opts.append({"n": a.text().strip(), "v": v}) + seen.add(v) + if len(opts) > 1: filters.append({"key": f"id{i}" if i else "id", "name": "分类", "value": opts}) + return filters + + def _api(self, path, data=None, params=None, method="GET", referer=None): + try: + h = self.headers.copy() + if referer: h["Referer"] = referer + func = self.session.post if method == "POST" else self.session.get + r = func(self.host + path, data=data, params=params, headers=h, timeout=3, allow_redirects=False) + if r.status_code in [301, 302] and r.headers.get("Location"): return self._abs(r.headers.get("Location").strip()) + try: + if u := r.json().get("url"): return self._abs(u.strip().replace(r"\/", "/")) + except: pass + if r.text.strip().startswith("http"): return r.text.strip() + except: pass + return "" + + def getpq(self, url): + import time + for _ in range(2): + try: return pq(self.session.get(self._abs(url), timeout=5).text) + except: time.sleep(0.1) + return pq("") + + def _abs(self, url): return url if url.startswith("http") else (f"http:{url}" if url.startswith("//") else f"{self.host}{'/' if not url.startswith('/') else ''}{url}") if url else "" + def e64(self, text): return b64encode(text.encode("utf-8")).decode("utf-8") + def d64(self, text): return b64decode(text.encode("utf-8")).decode("utf-8") \ No newline at end of file diff --git "a/spider/py/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].py" "b/spider/py/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].py" new file mode 100644 index 00000000..a703a59c --- /dev/null +++ "b/spider/py/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].py" @@ -0,0 +1,259 @@ +""" +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '爱玩音乐', + lang: 'hipy' +}) +""" + +import re +import sys +from base64 import b64encode, b64decode +from urllib.parse import quote +from pyquery import PyQuery as pq +from requests import Session, adapters +from urllib3.util.retry import Retry +from concurrent.futures import ThreadPoolExecutor, as_completed +sys.path.append('..') +from base.spider import Spider + +class Spider(Spider): + def init(self, extend=""): + self.host = "http://www.22a5.com" + self.session = Session() + retries = Retry(total=2, backoff_factor=0.5, status_forcelist=[429, 500, 502, 503, 504]) + adapter = adapters.HTTPAdapter(max_retries=retries, pool_connections=20, pool_maxsize=50) + self.session.mount("http://", adapter) + self.session.mount("https://", adapter) + self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"} + self.session.headers.update(self.headers) + + def getName(self): return "爱玩音乐" + def isVideoFormat(self, url): return bool(re.search(r'\.(m3u8|mp4|mp3|m4a|flv)(\?|$)', url or "", re.I)) + def manualVideoCheck(self): return False + def destroy(self): self.session.close() + + def homeContent(self, filter): + classes = [ + {"type_name": "电台", "type_id": "/radiolist/index.html"}, + {"type_name": "歌单", "type_id": "/playtype/index.html"}, + {"type_name": "专辑", "type_id": "/albumlist/index.html"}, + {"type_name": "歌手", "type_id": "/singerlist/index/index/index/index.html"}, + {"type_name": "高清MV", "type_id": "/mvlist/oumei.html"}, + {"type_name": "新歌榜", "type_id": "/list/new.html"}, + {"type_name": "TOP榜单", "type_id": "/list/top.html"} + ] + filters = {} + + fetch_targets = ["/list/new.html", "/list/top.html", "/mvlist/index.html", "/playtype/index.html", "/albumlist/index.html", "/radiolist/index.html"] + for path in fetch_targets: + if f_data := self._fetch_filters(path): + filters[path] = f_data + + if "/radiolist/index.html" not in filters: + filters["/radiolist/index.html"] = [ + {"key": "id", "name": "分类", "value": [ + {"n": "最新", "v": "index"}, {"n": "最热", "v": "hot"}, {"n": "有声小说", "v": "novel"}, + {"n": "相声", "v": "xiangyi"}, {"n": "音乐", "v": "music"}, {"n": "情感", "v": "emotion"}, + {"n": "国漫", "v": "game"}, {"n": "影视", "v": "yingshi"}, {"n": "脱口秀", "v": "talkshow"}, + {"n": "历史", "v": "history"}, {"n": "儿童", "v": "children"}, {"n": "教育", "v": "education"}, + {"n": "八卦", "v": "gossip"}, {"n": "推理", "v": "tuili"}, {"n": "头条", "v": "headline"} + ]} + ] + + filters["/singerlist/index/index/index/index.html"] = [ + {"key": "area", "name": "地区", "value": [{"n": "全部", "v": "index"}, {"n": "华语", "v": "huayu"}, {"n": "欧美", "v": "oumei"}, {"n": "韩国", "v": "hanguo"}, {"n": "日本", "v": "ribrn"}]}, + {"key": "sex", "name": "性别", "value": [{"n": "全部", "v": "index"}, {"n": "男", "v": "male"}, {"n": "女", "v": "girl"}, {"n": "组合", "v": "band"}]}, + {"key": "genre", "name": "流派", "value": [{"n": n, "v": v} for n, v in [("全部","index"),("流行","liuxing"),("电子","dianzi"),("摇滚","yaogun"),("嘻哈","xiha"),("R&B","rb"),("民谣","minyao"),("爵士","jueshi"),("古典","gudian")]]}, + {"key": "char", "name": "字母", "value": [{"n": "全部", "v": "index"}] + [{"n": chr(i), "v": chr(i).lower()} for i in range(65, 91)]} + ] + return {"class": classes, "filters": filters, "list": []} + + def homeVideoContent(self): return {"list": []} + + def categoryContent(self, tid, pg, filter, extend): + pg = int(pg or 1) + url = tid + if "/singerlist/" in tid: + p = tid.split('/') + if len(p) >= 6: + p[2], p[3], p[4] = extend.get("area", p[2]), extend.get("sex", p[3]), extend.get("genre", p[4]) + p[-1] = f"{extend.get('char', 'index')}.html" + url = "/".join(p) + elif "id" in extend and extend["id"] not in ["index", "top"]: + url = tid.replace("index.html", f"{extend['id']}.html").replace("top.html", f"{extend['id']}.html") + if url == tid: url = f"{tid.rsplit('/', 1)[0]}/{extend['id']}.html" + + if pg > 1: + url = re.sub(r'/\d+\.html$', '.html', url) + url = re.sub(r'_\d+\.html$', '.html', url) + + if "/singerlist/" in url or "/radiolist/" in url or "/mvlist/" in url or "/playtype/" in url or "/list/" in url: + url = url.replace(".html", f"/{pg}.html") + else: + url = url.replace(".html", f"_{pg}.html") + + doc = self.getpq(url) + items = doc(".play_list li, .video_list li, .pic_list li, .singer_list li, .ali li, .layui-row li") or doc(".base_l li") + return {"list": self._parse_list(items, tid), "page": pg, "pagecount": 9999, "limit": 90, "total": 999999} + + def searchContent(self, key, quick, pg="1"): + return {"list": self._parse_list(self.getpq(f"/so/{quote(key)}/{pg}.html")(".base_l li, .play_list li"), "search"), "page": int(pg)} + + def detailContent(self, ids): + url = self._abs(ids[0]) + doc = self.getpq(url) + title = self._clean(doc("h1").text() or doc("title").text() or "") + pic = self._abs(doc(".djpg img, .pic img, .djpic img").attr("src")) + vod = {"vod_id": url, "vod_name": title, "vod_pic": pic, "vod_play_from": "爱玩音乐", "vod_content": ""} + + if any(x in url for x in ["/playlist/", "/album/", "/list/", "/singer/", "/special/", "/radio/", "/radiolist/"]): + eps = self._get_eps(doc) + page_urls = set() + for a in doc(".page a, .dede_pages a, .pagelist a").items(): + href = a.attr("href") + if href and not href.startswith("javascript") and href != "#": + abs_url = self._abs(href) + if abs_url != url: + page_urls.add(abs_url) + + if page_urls: + sorted_urls = sorted(list(page_urls), key=lambda x: int(re.search(r'[_\/](\d+)\.html', x).group(1)) if re.search(r'[_\/](\d+)\.html', x) else 0) + with ThreadPoolExecutor(max_workers=5) as executor: + futures = [executor.submit(self._fetch_eps, u) for u in sorted_urls] + for f in futures: + try: + if more_eps := f.result(): + eps.extend(more_eps) + except: pass + + if eps: + vod["vod_play_from"], vod["vod_play_url"] = "播放列表", "#".join(eps) + return {"list": [vod]} + + play_list = [] + if mid := re.search(r'/(song|mp3|radio|radiolist|radioplay)/([^/]+)\.html', url): + sid = mid.group(2) + if pu := self._api("/js/play.php", data={"id": sid, "type": "music"}, method="POST", referer=url): + play_list.append(f"播放${self.e64('0@@@@'+pu)}") + lrc = f"{self.host}/plug/down.php?ac=music&lk=lrc&id={sid}" + play_list.append(f"歌词${self.e64('0@@@@'+lrc)}") + + elif vid := re.search(r'/(video|mp4)/([^/]+)\.html', url): + tasks = [] + with ThreadPoolExecutor(max_workers=3) as executor: + futures = {executor.submit(self._api, "/plug/down.php", None, {"ac": "vplay", "id": vid.group(2), "q": q}, "GET", url): n for n, q in [("蓝光", 1080), ("超清", 720), ("高清", 480)]} + for f in as_completed(futures): + if u := f.result(): + name = futures[f] + play_list.append(f"{name}${self.e64('0@@@@'+u)}") + play_list.sort(key=lambda x: {"蓝":0, "超":1, "高":2}.get(x[0], 3)) + + vod["vod_play_url"] = "#".join(play_list) if play_list else f"解析失败${self.e64('1@@@@'+url)}" + return {"list": [vod]} + + def _fetch_eps(self, url): + return self._get_eps(self.getpq(url)) + + def _get_eps(self, doc): + local_eps = [] + for li in doc(".play_list li, .song_list li, .music_list li").items(): + href = li("a").attr("href") + if not href or not re.search(r'/(song|mp3|radio|radiolist|radioplay)/', href): continue + song_name = self._clean(li("a").eq(0).text() or li(".name").text()) + local_eps.append(f"{song_name}${self.e64('1@@@@'+self._abs(href))}") + return local_eps + + def playerContent(self, flag, id, vipFlags): + url = self.d64(id).split("@@@@")[-1].replace(r"\/", "/") + if ".html" in url and not self.isVideoFormat(url): + if mid := re.search(r'/(song|mp3|radio|radiolist|radioplay)/([^/]+)\.html', url): + url = self._api("/js/play.php", data={"id": mid.group(2), "type": "music"}, method="POST", referer=url) or url + + elif vid := re.search(r'/(video|mp4)/([^/]+)\.html', url): + with ThreadPoolExecutor(max_workers=3) as executor: + futures = [executor.submit(self._api, "/plug/down.php", None, {"ac": "vplay", "id": vid.group(2), "q": q}, "GET", url) for q in [1080, 720, 480]] + for f in as_completed(futures): + if v_url := f.result(): + url = v_url + executor.shutdown(wait=False) + break + return {"parse": 0, "url": url, "header": {"User-Agent": self.headers["User-Agent"]}} + + def localProxy(self, param): + if param.get("type") == "img": + try: + r = self.session.get(param["url"], headers={"Referer": "https://www.2t58.com/"}, timeout=5) + if r.status_code == 200: return [200, r.headers.get("Content-Type", "image/jpeg"), r.content, {}] + except: pass + return None + + def _parse_list(self, items, tid=""): + res = [] + for li in items.items(): + a = li("a").eq(0) + href = a.attr("href") + if not href or href == "/" or any(x in href for x in ["/user/", "/login/", "javascript"]): continue + name = self._clean(li(".name").text() or a.attr("title") or a.text()) + if not name: continue + + img = li("img").attr("src") or "" + if img: + img = self._abs(img.replace('120', '500')) + pic = f"{self.getProxyUrl()}&url={img}&type=img" + else: pic = "" + + url = self._abs(href) + is_singer = "/singerlist/" in tid and "/singer/" in url + style = {"type": "oval"} if is_singer else ({"type": "list"} if any(x in tid for x in ["/list/", "/playtype/", "/albumlist/"]) else {"type": "rect", "ratio": 1.33}) + res.append({"vod_id": url, "vod_name": name, "vod_pic": pic, "vod_tag": "", "style": style}) + return res + + def _clean(self, text): + return re.sub(r'(爱玩音乐网|视频下载说明|视频下载地址|www\.2t58\.com|MP3免费下载|LRC歌词下载|全部歌曲|\[第\d+页\]|刷新|每日推荐|最新|热门|推荐|MV|高清|无损)', '', text, flags=re.I).strip() + + def _fetch_filters(self, url): + doc = self.getpq(url) + selectors = [".ilingku_fl", ".class_list", ".screen_list", ".box_list", ".nav_list"] + if not (groups := [doc(s) for s in selectors if doc(s)]): return [] + + filters = [] + for i, group in enumerate(groups): + opts = [{"n": "全部", "v": "top" if "top" in url else "index"}] + seen = {opts[0]['v']} + for a in group("a").items(): + href = a.attr("href") + if not href: continue + v = href.split("?")[0].rstrip('/').split('/')[-1].replace('.html','') + if v not in seen: + opts.append({"n": a.text().strip(), "v": v}) + seen.add(v) + if len(opts) > 1: filters.append({"key": f"id{i}" if i else "id", "name": "分类", "value": opts}) + return filters + + def _api(self, path, data=None, params=None, method="GET", referer=None): + try: + h = self.headers.copy() + if referer: h["Referer"] = referer + func = self.session.post if method == "POST" else self.session.get + r = func(self.host + path, data=data, params=params, headers=h, timeout=3, allow_redirects=False) + if r.status_code in [301, 302] and r.headers.get("Location"): return self._abs(r.headers.get("Location").strip()) + try: + if u := r.json().get("url"): return self._abs(u.strip().replace(r"\/", "/")) + except: pass + if r.text.strip().startswith("http"): return r.text.strip() + except: pass + return "" + + def getpq(self, url): + import time + for _ in range(2): + try: return pq(self.session.get(self._abs(url), timeout=5).text) + except: time.sleep(0.1) + return pq("") + + def _abs(self, url): return url if url.startswith("http") else (f"http:{url}" if url.startswith("//") else f"{self.host}{'/' if not url.startswith('/') else ''}{url}") if url else "" + def e64(self, text): return b64encode(text.encode("utf-8")).decode("utf-8") + def d64(self, text): return b64decode(text.encode("utf-8")).decode("utf-8") \ No newline at end of file From d1518cb70ec0bcac91da77d862cca118c15c3590 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 20:09:46 +0800 Subject: [PATCH 09/99] =?UTF-8?q?=E5=88=A0=E9=99=A4DJ=E9=9F=B3=E4=B9=90[?= =?UTF-8?q?=E5=90=AC].js=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\351\237\263\344\271\220[\345\220\254].js" | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 "spider/js_dr2/DJ\351\237\263\344\271\220[\345\220\254].js" diff --git "a/spider/js_dr2/DJ\351\237\263\344\271\220[\345\220\254].js" "b/spider/js_dr2/DJ\351\237\263\344\271\220[\345\220\254].js" deleted file mode 100644 index 3a9dc395..00000000 --- "a/spider/js_dr2/DJ\351\237\263\344\271\220[\345\220\254].js" +++ /dev/null @@ -1,47 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 0, - quickSearch: 0, - title: 'DJ音乐', - '类型': '影视', - lang: 'dr2' -}) -*/ - -// 道长 drpy仓库 https://gitcode.net/qq_32394351/dr_py -// 道长 drpy安卓本地搭建说明 https://code.gitlink.org.cn/api/v1/repos/hjdhnx/dr_py/blob/master/%E5%AE%89%E5%8D%93%E6%9C%AC%E5%9C%B0%E6%90%AD%E5%BB%BA%E8%AF%B4%E6%98%8E.md -// 道长 drpy写源 模板规则说明 https://gitcode.net/supertlo/dr_py#%E6%A8%A1%E6%9D%BF%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E -// 道长 drpy写源 套模模版 https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/%E6%A8%A1%E6%9D%BF.js -// 道长 drpy写源 影片教程 http://101.34.67.237:5244/%E6%95%99%E8%82%B2/drpy -// 道长 drpy写源 影片教程(m3u8切片) https://freedrpy.run.goorm.io/txt/jc/playlist.m3u8 -// 海阔下载 https://haikuo.lanzoui.com/u/GoldRiver -// Pluto Player官方TG https://t.me/PlutoPlayer -// Pluto Player官方TG https://t.me/PlutoPlayerChannel - -// pluto 播放正常 -// 俊老的壳或PythonBox 在rules新增底下设定 即可正常播放 -// {"host":"www.djuu.com","rule":["mp4.djuu.com"]}, - -var rule = { - title:'DJ音乐', - host:'http://www.djuu.com', - homeUrl:'/exclusive/115_1.html',//网站的首页链接,可以是完整路径或者相对路径,用于分类获取和推荐获取 fyclass是分类标签 fypage是页数 - url:'/djlist/fyclass_fypage.html', - searchUrl:'/search?musicname=**', - searchable:2, - quickSearch:0, - class_parse:'#top_banner_bg div;a&&Text;a&&href;/djlist/(\\d+)_1.html', - headers:{ - 'User-Agent':'PC_UA' - }, - timeout:5000, - play_parse:true, - lazy:'', - limit:6, - double:false, - 推荐:'*', - 一级:'.list_musiclist tr:gt(0);a&&title;img&&src;.cor999:eq(1)&&Text;a&&href', - 二级:'*', - 搜索:'*;*;*;.sc_1&&Text;*', -} From 6fe76983811e2d976a021ff66e6d7d715ba8f027 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 20:27:17 +0800 Subject: [PATCH 10/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0config/map.txt=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/map.txt b/config/map.txt index 756117df..1d3a929f 100644 --- a/config/map.txt +++ b/config/map.txt @@ -30,9 +30,14 @@ UC分享@@?type=url¶ms=../json/UC分享.json@@UC分享[盘] 网盘[模板]@@?type=url¶ms=../json/域名配置.json$欧歌@@欧歌ᵐ[盘] 网盘[模板]@@?type=url¶ms=../json/域名配置.json$至臻@@至臻ᵐ[盘] AppFox@@http://app.hktvyb.cc@@TVB云播[AFX] +AppFox@@{"host":"http://www.yezitv.top/dtym.json"}@@木瓜影视[AFX] +AppFox@@{"host":"http://nico.oiio.fun"}@@花柳影视[AFX] AppFox@@{"host":"https://cunchu8.obs.cn-north-4.myhuaweicloud.com/config.json","parse":{"JL4K":"http://194.147.100.155:7891/?url="}}@@火猫影视[AFX] AppFei@@https://ysc.yy-fun.cc/feiapp@@呀哩4K[AF] AppFei@@https://ysa.yy-fun.cc/feiapp@@森林动漫[AF] +AppGet@@{"host":"https://snysw.xyz/mf4kzs327.txt","key":"1234567887654321"}@@魔方[AG¹] +AppGet@@{"host":"https://gitee.com/wmmoliill/wimg/raw/master/img/bk/9.txt","key":"88689667dce61725"}@@茉莉[AG¹] +AppGet@@{"host":"http://ys.qist.top","key":"2SWSPFxugBLPPOKo"}@@旗星[AG¹] AppGet@@{"host":"https://api1.bffree.cn","key":"2015692015692015"}@@橘子[AG¹] AppGet@@{"host":"https://dy.58ys.vip","key":"JEWibY1AgWF0V1xx"}@@五八[AG¹] AppGet@@{"host":"https://mac.555618.xyz","key":"#getapp@TMD@2025"}@@玲珑[AG¹] From 4d0472c88379c014f72d3a0adfbedd115e22d2f9 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 14 Jan 2026 20:42:47 +0800 Subject: [PATCH 11/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0config/map.txt=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/config/map.txt b/config/map.txt index 1d3a929f..a6603726 100644 --- a/config/map.txt +++ b/config/map.txt @@ -57,6 +57,7 @@ AppV2²@@http://38.47.213.61:41271@@闪影[AV²] AppV2²@@http://v.lnhaozhenjin.cn@@好震惊[AV²] AppV2²@@http://jxfmax.juxiafan.com@@剧下饭[AV²] AppV1@@http://ziyuncms.feifan12.xyz/api.php@@紫云[AV¹] +getapp3.4.4@@{"host":"https://staraugust123456.oss-cn-hangzhou.aliyuncs.com/2.txt","datakey":"staraugust123456","api":2}@@云云[AG³] getapp3.4.4@@{"host":"https://jingyu4k-1312635929.cos.ap-nanjing.myqcloud.com/1.json","datakey":"AAdgrdghjfgswerA","api":2}@@鲸鱼影视[AG³] getapp3.4.4@@{"host":"https://www.guahd.com/1.txt","key":"f2A7D4B9E8C16531"}@@瓜萌[AG³] getapp3.4.4@@{"host":"https://99.jl8.top/1.txt","key":"xnybssspqtwotuwj"}@@七月[AG³] From 9740269e788c5dd36aab35cc787133574d9e7488 Mon Sep 17 00:00:00 2001 From: Taois Date: Wed, 14 Jan 2026 23:44:11 +0800 Subject: [PATCH 12/99] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=87=A0=E4=B8=AA?= =?UTF-8?q?=E9=9F=B3=E4=B9=90=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\212\250\346\274\253[\346\274\253].js" | 9 ++- ...\351\237\263\344\271\220[\345\220\254].js" | 45 ++++++----- ...45\225\212\345\223\210DJ[\345\220\254].js" | 10 ++- ...\347\243\201\345\234\272[\345\220\254].js" | 78 ++++++++++--------- ...\345\220\254\344\271\246[\345\220\254].js" | 57 ++++++++------ 5 files changed, 121 insertions(+), 78 deletions(-) diff --git "a/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" "b/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" index e11949df..9f9ded18 100644 --- "a/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" +++ "b/spider/catvod/\345\227\267\345\221\234\345\212\250\346\274\253[\346\274\253].js" @@ -4,7 +4,14 @@ title: '嗷呜动漫', author: '小可乐/v6.1.1' "ext": { "host": "xxxx", //站点网址 "timeout": 6000 //请求超时,单位毫秒 -} +} +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '嗷呜动漫[漫]', + lang: 'cat' +}) */ import {Crypto} from 'assets://js/lib/cat.js'; diff --git "a/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" index 8b7f56e7..f5266a62 100644 --- "a/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" +++ "b/spider/js/DJ\351\237\263\344\271\220[\345\220\254].js" @@ -12,31 +12,40 @@ */ var rule = { - title:'DJ音乐', - host:'http://www.djuu.com', - homeUrl:'/exclusive/115_1.html', - url:'/djlist/fyclass_fypage.html', - searchUrl:'/search?musicname=**', + title: 'DJ音乐', + host: 'http://www.djuu.com', + homeUrl: '/exclusive/115_1.html', + url: '/djlist/fyclass_fypage.html', + searchUrl: '/search?musicname=**', author: 'EylinSir', logo: 'https://pic.289.com/up/2023-12/20231219154340126.png', hikerListCol: 'icon_4', - searchable:2, - quickSearch:0, + searchable: 2, + quickSearch: 0, class_name: '迪高串烧&慢摇串烧&慢歌串烧&中文Remix&外文Remix&HOUSE&HOUSE&霓虹风格&Mashup&中文DISCO&外文DISCO', class_url: '1&2&3&4&5&6&7&8&9&10', - headers:{ - 'User-Agent':'PC_UA' + headers: { + 'User-Agent': 'PC_UA' }, - timeout:5000, - limit:6, - double:false, - play_parse:true, - lazy: async function() { + timeout: 5000, + limit: 6, + double: false, + play_parse: true, + lazy: async function () { let {input} = this; + log("input:", input); + let html = await request(input); + // log(html) + let music = html.match(/var\s+music\s*=\s*(\{[\s\S]*?\})/)[1]; + music = JSON5.parse(music); + // log(music); + // 算法来自:https://www.djuu.com/static/js/common.js + input = urljoin(input, "//mp4.djuu.com/" + music.file + ".m4a"); + // log(input); return input; }, - 推荐:'*', - 一级:'.list_musiclist tr:gt(0);a&&title;img&&src;.cor999:eq(1)&&Text;a&&href', - 二级:'*', - 搜索:'*;*;*;.sc_1&&Text;*', + 推荐: '*', + 一级: '.list_musiclist tr:gt(0);a&&title;img&&src;.cor999:eq(1)&&Text;a&&href', + 二级: '*', + 搜索: '*;*;*;.sc_1&&Text;*', } diff --git "a/spider/js/\345\225\212\345\223\210DJ[\345\220\254].js" "b/spider/js/\345\225\212\345\223\210DJ[\345\220\254].js" index a1bc9e9b..f77ee4ba 100644 --- "a/spider/js/\345\225\212\345\223\210DJ[\345\220\254].js" +++ "b/spider/js/\345\225\212\345\223\210DJ[\345\220\254].js" @@ -28,7 +28,15 @@ var rule = { // console.log('input:', input); let html = await request(input); let _url = pdfh(html, 'video&&source&&src'); - return {parse: 0, url: _url, js: ''}; + return { + parse: 0, + url: _url, + js: '', + header: { + referer: 'https://m.ahadj.com/', + 'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Mobile Safari/537.36' + } + }; }, 推荐: '*', searchUrl: '/search/?key=**&page=fypage.html', diff --git "a/spider/js/\351\237\263\344\271\220\347\243\201\345\234\272[\345\220\254].js" "b/spider/js/\351\237\263\344\271\220\347\243\201\345\234\272[\345\220\254].js" index bab53c50..a333be94 100755 --- "a/spider/js/\351\237\263\344\271\220\347\243\201\345\234\272[\345\220\254].js" +++ "b/spider/js/\351\237\263\344\271\220\347\243\201\345\234\272[\345\220\254].js" @@ -10,45 +10,51 @@ */ var rule = { - title: '音乐磁场', - host: 'https://hifini.net/', - url: '/forum-fyclass-fypage.htm?orderby=lastpid&follow=0', - searchUrl: '/search-**-1-0-fypage.htm', - class_parse: '.navbar-nav li;a&&Text;a&&href;forum-(.*/?).htm', - searchable: 2, - quickSearch: 0, - filterable: 0, - headers: { - 'User-Agent': 'MOBILE_UA', - }, - play_parse: true, - lazy: ` -let html = request(input); + title: '音乐磁场', + host: 'https://hifini.net/', + url: '/forum-fyclass-fypage.htm?orderby=lastpid&follow=0', + searchUrl: '/search-**-1-0-fypage.htm', + class_parse: '.navbar-nav li;a&&Text;a&&href;forum-(.*/?).htm', + searchable: 2, + quickSearch: 0, + filterable: 0, + headers: { + 'User-Agent': 'MOBILE_UA', + }, + play_parse: true, + lazy: $js.toString(async () => { + let html = await request(input); // 1️⃣ 直链 -let m = html.match(/url:\\s*"(https?:[^"]+)"/); -let playUrl = m ? m[1] : input; +// let m = html.match(/url:\s*"(https?:[^"]+)"/); +// let playUrl = m ? m[1] : input; + const urlPropertyPattern = /url\s*:\s*['"](https?:\/\/[^'"]+)['"]/gi; + const matches = [...html.matchAll(urlPropertyPattern)]; + const urlValues = matches.map(match => match[1]); + console.log(urlValues); + let playUrl = urlValues[0] || input; // 2️⃣ 歌词 -let lyric = []; -let ps = html.match(/

    (.*?)<\\/p>/g) || []; -for(let p of ps){ - let t = p.replace(/<[^>]+>/g,'').trim(); - if(!t) continue; - if(/下载链接|提取码|隐藏内容/.test(t)) break; - lyric.push(t); -} + let lyric = []; + let ps = html.match(/

    (.*?)<\/p>/g) || []; + for (let p of ps) { + let t = p.replace(/<[^>]+>/g, '').trim(); + if (!t) continue; + if (/下载链接|提取码|隐藏内容/.test(t)) break; + lyric.push(t); + } -input = { - parse: 0, - url: playUrl, - lyric: lyric.join('\\n') -}; -`, - limit: 6, - double: true, - 推荐: '.cbox_list;*;*;*;*;*', - 一级: 'ul.list-unstyled li:gt(2);.subject&&Text;img&&src;.media-body&&Text;.subject a&&href', - 二级: '*', - 搜索: '*', + input = { + parse: 0, + url: playUrl, + lyric: lyric.join('\n') + }; + return input + }), + limit: 6, + double: true, + 推荐: '.cbox_list;*;*;*;*;*', + 一级: 'ul.list-unstyled li:gt(2);.subject&&Text;img&&src;.media-body&&Text;.subject a&&href', + 二级: '*', + 搜索: '*', } diff --git "a/spider/js_dr2/\347\210\261\344\270\212\345\220\254\344\271\246[\345\220\254].js" "b/spider/js_dr2/\347\210\261\344\270\212\345\220\254\344\271\246[\345\220\254].js" index 2a00a53e..40ee8ad7 100644 --- "a/spider/js_dr2/\347\210\261\344\270\212\345\220\254\344\271\246[\345\220\254].js" +++ "b/spider/js_dr2/\347\210\261\344\270\212\345\220\254\344\271\246[\345\220\254].js" @@ -10,29 +10,42 @@ */ var rule = { - title:'爱上你听书网', - host:'https://www.230ts.net', - url:'/sort/fyclass/fypage.html', - searchUrl:'/search.html?searchtype=name&searchword=**&page=fypage', - searchable:2, - quickSearch:0, - headers:{ - 'User-Agent':'PC_UA' + title: '爱上你听书网', + host: 'https://www.230ts.net', + url: '/sort/fyclass/fypage.html', + searchUrl: '/search.html?searchtype=name&searchword=**&page=fypage', + searchable: 2, + quickSearch: 0, + headers: { + 'User-Agent': 'PC_UA' }, - timeout:5000, + timeout: 5000, class_parse: '.nav-ol&&li:gt(0):lt(6);a&&Text;a&&href;.*/(\\w+).html', - play_parse:true, - lazy:'js:input=input.replace("www","wap")', - limit:6, - 推荐:'#myTab_Content1&&li;.tab-book-title&&Text;*;.tab-book-author&&Text;*', - 一级:'ul.list-works&&li;.list-book-dt--span&&Text;.lazy&&data-original;.book-author:eq(2)&&a&&Text;a&&href', - 二级:{ - title:'.book-cover&&alt;.book-info&&dd--span:eq(1)&&Text', - img:'.book-cover&&src', - desc:'.book-info&&dd:eq(4)&&Text;;;.book-info&&dd--span:eq(3)&&Text;.book-info&&dd--span:eq(2)&&Text', - content:'.book-des&&Text', - tabs:'.playlist-top&&h2', - lists:'#playlist:eq(#id)&&li', + play_parse: true, + lazy: $js.toString(() => { + let html = request(input); + let src = pd(html, 'iframe#play&&src', input); + log('src:' + src); + html = request(src); + const regex = /mp3\s*:\s*'([^']+)'/; + const match = html.match(regex); + if (match && match[1].includes('auth_key')) { + // 替换变量部分为 .mp3. + src = match[1].replace(/'([^']*)'\s*\+\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*\+\s*'([^']*)'/, '$1.mp3.$2'); + log('match src:' + src); + } + input = src + }), + limit: 6, + 推荐: '#myTab_Content1&&li;.tab-book-title&&Text;*;.tab-book-author&&Text;*', + 一级: 'ul.list-works&&li;.list-book-dt--span&&Text;.lazy&&data-original;.book-author:eq(2)&&a&&Text;a&&href', + 二级: { + title: '.book-cover&&alt;.book-info&&dd--span:eq(1)&&Text', + img: '.book-cover&&src', + desc: '.book-info&&dd:eq(4)&&Text;;;.book-info&&dd--span:eq(3)&&Text;.book-info&&dd--span:eq(2)&&Text', + content: '.book-des&&Text', + tabs: '.playlist-top&&h2', + lists: '#playlist:eq(#id)&&li', }, - 搜索:'*', + 搜索: '*', } \ No newline at end of file From 0f351d6fa79defdfdfd7973c32be1aa5455a12a7 Mon Sep 17 00:00:00 2001 From: Taois Date: Thu, 15 Jan 2026 00:10:19 +0800 Subject: [PATCH 13/99] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...04\345\260\217\350\257\264[\344\271\246].js" | 17 ++++++++++++----- ...71\345\260\217\350\257\264[\344\271\246].js" | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" index 644fe3f7..b659fa25 100644 --- "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" @@ -14,10 +14,14 @@ // http://localhost:5757/api/番茄小说[书]?wd=斩神&pg=2 // http://localhost:5757/api/番茄小说[书]?play=7432172914662720025&flag=番茄小说 +// 对接API:https://qkfqapi.vv9v.cn/docs +// https://github.com/POf-L/Fanqie-novel-Downloader/blob/main/novel_downloader.py + const {getRandomFromList} = $.require('./_lib.random.js'); const {requestHtml} = $.require('./_lib.request.js'); // const fqweb_host = 'http://fqweb.jsj66.com'; -const fqweb_host = 'http://fanqie.mduge.com'; +// const fqweb_host = 'http://fanqie.mduge.com'; +const fqweb_host = 'https://qkfqapi.vv9v.cn'; var rule = { 类型: '小说', @@ -26,7 +30,8 @@ var rule = { host: 'https://fanqienovel.com/', homeUrl: 'https://fanqienovel.com/api/author/book/category_list/v0/', url: '/api/author/library/book_list/v0/?page_count=18&page_index=(fypage-1)&gender=1&category_id=fyclass&creation_status=-1&word_count=-1&book_type=-1&sort=0#fyfilter', - searchUrl: fqweb_host + '/search?query=**&page=fypage', + // searchUrl: fqweb_host + '/search?query=**&page=fypage', + searchUrl: fqweb_host + '/api/search?key=**&tab_type=3&offset=0&page=fypage', searchable: 2, quickSearch: 0, filterable: 1, @@ -148,7 +153,7 @@ var rule = { }, searchHandel: function (json) { return { - data: json.data.search_tabs[0].data + data: json.data.search_tabs[5].data }; }, 搜索: async function (wd, quick, pg) { @@ -180,7 +185,8 @@ var rule = { let content_url = ''; // 正文获取接口 // content_url = `http://fqweb.jsj66.com/content?item_id=${input}`; // content_url = `https://fanqienovel.com/reader/${input}?enter_from=reader`; - content_url = `${fqweb_host}/content?item_id=${input}`; + // content_url = `${fqweb_host}/content?item_id=${input}`; + content_url = `${fqweb_host}/api/content?tab=小说&item_id=${input}`; /* log(content_url); @@ -200,7 +206,8 @@ var rule = { */ let json = JSON.parse(html); - content = json.content.replace(/\n\n妍󠇕希󠆖󠅽󠇕󠆨󠅼󠄡󠄩󠄠󠄩󠄣󠄣󠄢󠄨󠄨󠄩\n/g, "\n"); + // content = json.content.replace(/\n\n妍󠇕希󠆖󠅽󠇕󠆨󠅼󠄡󠄩󠄠󠄩󠄣󠄣󠄢󠄨󠄨󠄩\n/g, "\n"); + content = json.data.content; // print(content) let ret = JSON.stringify({ title, diff --git "a/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" index 19305d76..99a113b4 100644 --- "a/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" @@ -26,7 +26,7 @@ var rule = { filter_url: '', filter_def: {}, headers: { - 'User-Agent': 'MOBILE_UA', + 'User-Agent': 'PC_UA', }, timeout: 5000, hikerListCol: "text_1", From b1b4452835ec21c1dd043b761a8dd590d2febb4a Mon Sep 17 00:00:00 2001 From: Taois Date: Thu, 15 Jan 2026 00:13:16 +0800 Subject: [PATCH 14/99] =?UTF-8?q?fix:=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ docs/updateRecord.md | 6 ++++++ package.json | 2 +- public/index.html | 2 ++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index da5f1e36..9e7990da 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,10 @@ nodejs作为服务端的drpy实现。全面升级异步写法 ## 更新记录 +### 20260115 + +更新至V1.3.17 + ### 20260113 更新至V1.3.16 diff --git a/docs/updateRecord.md b/docs/updateRecord.md index 6959904f..8fe8d811 100644 --- a/docs/updateRecord.md +++ b/docs/updateRecord.md @@ -1,5 +1,11 @@ # drpyS更新记录 +### 20260115 + +更新至V1.3.17 + +1. 新增一些源 & 修复一些源 + ### 20260113 更新至V1.3.16 diff --git a/package.json b/package.json index af0c9f5a..25b196bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "drpy-node", - "version": "1.3.16", + "version": "1.3.17", "main": "index.js", "type": "module", "scripts": { diff --git a/public/index.html b/public/index.html index 6b7fb650..796ff944 100644 --- a/public/index.html +++ b/public/index.html @@ -67,6 +67,8 @@

    免费壳子推荐

  • 皮卡丘
  • 更新记录

    +

    20260115

    +

    更新至V1.3.17

    20260113

    更新至V1.3.16

    20260112

    From 9c650c5374f8bb83777f4a37fd01d338f890138b Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Thu, 15 Jan 2026 10:53:05 +0800 Subject: [PATCH 15/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 3 +++ "spider/js/TG\346\220\234[\346\220\234].js" | 2 +- "spider/js/TG\347\233\230\346\220\234[\346\220\234].js" | 2 +- "spider/js/TG\351\242\221\351\201\223.js" | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/config/map.txt b/config/map.txt index a6603726..83951c69 100644 --- a/config/map.txt +++ b/config/map.txt @@ -43,6 +43,9 @@ AppGet@@{"host":"https://dy.58ys.vip","key":"JEWibY1AgWF0V1xx"}@@五八[AG¹] AppGet@@{"host":"https://mac.555618.xyz","key":"#getapp@TMD@2025"}@@玲珑[AG¹] AppGet@@{"host":"https://app.omofun1.top","key":"66dc309cbeeca454"}@@OMOfun[AG¹] AppGet@@{"host":"http://tv.yy-fun.cc","key":"qkxnwkfjwpcnwycl"}@@丫丫动漫[AG¹] +AppGet@@{"host":"https://www.cyfz.vip","key":"e72cdfd629e8895d"}@@方舟动漫[AG¹] +AppGet@@{"host":"http://cic.aicg.fun","key":"2c4h36abd96se10u"}@@元咲动漫[AG¹] +AppGet@@{"host":"https://www.gugu3.com","key":"nKfZ8KX6JTNWRzTD"}@@咕咕动漫[AG¹] AppSk@@{"host":"https://skyappdata-1321528676.cos.accelerate.myqcloud.com/4kapp/appipr.txt","key":"ygcnbckhcuvygdyb","iv":"4023892775143708"}@@即看影视[AS] AppSk@@{"host":"https://kankelm.cn:2024/appdomain.txt","key":"ygcnbcvybqqckwqy","iv":"1583560747143708"}@@看客联盟[AS] AppSk@@{"host":"https://dmsk.oss-rg-china-mainland.aliyuncs.com/dmapp/dmapi.txt","key":"ygcnbcobcegtgigg","iv":"4058263969143708"}@@2k动漫[AS] diff --git "a/spider/js/TG\346\220\234[\346\220\234].js" "b/spider/js/TG\346\220\234[\346\220\234].js" index 5d5ff90c..5a98a5cf 100755 --- "a/spider/js/TG\346\220\234[\346\220\234].js" +++ "b/spider/js/TG\346\220\234[\346\220\234].js" @@ -10,7 +10,7 @@ }) */ -const Pan_API = 'http://127.0.0.1:6080'; // 网盘链接有效性检测过滤api,需自行替换 +const Pan_API = 'https://pancheck.banye.tech:7777'; // 网盘链接有效性检测过滤api,需自行替换 const Pan_Sift = []; const DEFAULT_CHANNELS = 'douerpan,bdwpzhpd,wydwpzy,sgkwpzy,zyywpzy,Baidu_Netdisk,PanjClub,youxigs,yunpanuc,zyfb123,ysxb48,xiangnikanj';//定义频道 const DEFAULT_SOURCES = ['百度网盘', '夸克网盘', 'UC网盘', '移动云盘', '天翼云盘', '115网盘', '阿里云盘', '123云盘'];//定义搜索网盘类型及顺序 diff --git "a/spider/js/TG\347\233\230\346\220\234[\346\220\234].js" "b/spider/js/TG\347\233\230\346\220\234[\346\220\234].js" index 9ab16fb4..4629447e 100644 --- "a/spider/js/TG\347\233\230\346\220\234[\346\220\234].js" +++ "b/spider/js/TG\347\233\230\346\220\234[\346\220\234].js" @@ -10,7 +10,7 @@ }) */ -const Pan_API = 'http://127.0.0.1:6080'; // PanCheck的API地址 自行替换 +const Pan_API = 'https://pancheck.banye.tech:7777'; // PanCheck的API地址 自行替换 const Pan_So = 'https://so.252035.xyz'; // PanSou地址,自行替换 const PAN_TYPES = '百度网盘,夸克网盘,UC网盘,天翼云盘,移动云盘'; // 默认搜索的网盘类型和排序,逗号分隔 const MAX_RESULTS = 15; // 默认搜索结果数量 (每个网盘类型最多15条) diff --git "a/spider/js/TG\351\242\221\351\201\223.js" "b/spider/js/TG\351\242\221\351\201\223.js" index ffbbdd60..85011738 100755 --- "a/spider/js/TG\351\242\221\351\201\223.js" +++ "b/spider/js/TG\351\242\221\351\201\223.js" @@ -93,7 +93,7 @@ const rule = { host: 'https://t.me', url: '/s/fyclass', searchUrl: '?q=**', - Pan_API: 'http://127.0.0.1:6080', // 网盘链接有效性检测过滤api,需自行替换 + Pan_API: 'https://pancheck.banye.tech:7777', // 网盘链接有效性检测过滤api,需自行替换 logo: 'https://api.xinac.net/icon/?url=https://t.me', searchable: 1, quickSearch: 1, From 200a79cfbf2fe6ed903bfa3c7615a16563c5bf48 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Thu, 15 Jan 2026 10:54:43 +0800 Subject: [PATCH 16/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TG\351\242\221\351\201\223\351\205\215\347\275\256.json" | 4 ---- 1 file changed, 4 deletions(-) diff --git "a/json/TG\351\242\221\351\201\223\351\205\215\347\275\256.json" "b/json/TG\351\242\221\351\201\223\351\205\215\347\275\256.json" index 273f60a0..6cda37ec 100644 --- "a/json/TG\351\242\221\351\201\223\351\205\215\347\275\256.json" +++ "b/json/TG\351\242\221\351\201\223\351\205\215\347\275\256.json" @@ -23,10 +23,6 @@ "type_id": "yunpanuc", "type_name": "UC资源" }, - { - "type_id": "xiangnikanj", - "type_name": "短剧频道" - }, { "type_id": "PanjClub", "type_name": "盘酱酱Club" From 5383673e47d88bfe2b9cd7117ea97b11d25b26e6 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Thu, 15 Jan 2026 14:15:14 +0800 Subject: [PATCH 17/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 3 - ...\346\235\277\351\205\215\347\275\256.json" | 200 +++++++++++++++++- 2 files changed, 192 insertions(+), 11 deletions(-) diff --git a/config/map.txt b/config/map.txt index 83951c69..a6603726 100644 --- a/config/map.txt +++ b/config/map.txt @@ -43,9 +43,6 @@ AppGet@@{"host":"https://dy.58ys.vip","key":"JEWibY1AgWF0V1xx"}@@五八[AG¹] AppGet@@{"host":"https://mac.555618.xyz","key":"#getapp@TMD@2025"}@@玲珑[AG¹] AppGet@@{"host":"https://app.omofun1.top","key":"66dc309cbeeca454"}@@OMOfun[AG¹] AppGet@@{"host":"http://tv.yy-fun.cc","key":"qkxnwkfjwpcnwycl"}@@丫丫动漫[AG¹] -AppGet@@{"host":"https://www.cyfz.vip","key":"e72cdfd629e8895d"}@@方舟动漫[AG¹] -AppGet@@{"host":"http://cic.aicg.fun","key":"2c4h36abd96se10u"}@@元咲动漫[AG¹] -AppGet@@{"host":"https://www.gugu3.com","key":"nKfZ8KX6JTNWRzTD"}@@咕咕动漫[AG¹] AppSk@@{"host":"https://skyappdata-1321528676.cos.accelerate.myqcloud.com/4kapp/appipr.txt","key":"ygcnbckhcuvygdyb","iv":"4023892775143708"}@@即看影视[AS] AppSk@@{"host":"https://kankelm.cn:2024/appdomain.txt","key":"ygcnbcvybqqckwqy","iv":"1583560747143708"}@@看客联盟[AS] AppSk@@{"host":"https://dmsk.oss-rg-china-mainland.aliyuncs.com/dmapp/dmapi.txt","key":"ygcnbcobcegtgigg","iv":"4058263969143708"}@@2k动漫[AS] diff --git "a/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" "b/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" index 00d03223..acca5464 100644 --- "a/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" +++ "b/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" @@ -23,6 +23,198 @@ "password": "", "会员时长": "", "lazyheader": {} + }, + "仓鼠": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://ceshi307386.oss-cn-beijing.aliyuncs.com/ceshi421.txt", + "key": "da61247f5b662597", + "iv": "da61247f5b662597", + "verify": "true" + }, + "紫金": { + "muban": "AppGet", + "host": "", + "hosturl": "https://snysw.xyz/mf4kzs327.txt", + "key": "1234567887654321", + "iv": "1234567887654321", + "verify": "true" + }, + "云云": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://staraugust123456.oss-cn-hangzhou.aliyuncs.com/2.txt", + "key": "staraugust123456", + "iv": "staraugust123456", + "verify": "true" + }, + "奇奇": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://yun-1316442804.cos.ap-guangzhou.myqcloud.com/a.txt", + "key": "123456789abcdefg", + "iv": "123456789abcdefg", + "verify": "true" + }, + "鲸鱼": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://jingyu4k-1312635929.cos.ap-nanjing.myqcloud.com/1.json", + "key": "AAdgrdghjfgswerA", + "iv": "AAdgrdghjfgswerA", + "verify": "true" + }, + "咖啡": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://daen-1256234123.cos.ap-shanghai.myqcloud.com/MuQi/mqxh.txt", + "key": "37kj83zs1q16jk6t", + "iv": "37kj83zs1q16jk6t", + "verify": "true" + }, + "小猪": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://tiantangyoulu.oss-cn-beijing.aliyuncs.com/tengxunyun.txt", + "key": "seb5tq9mykp2w9ry", + "iv": "seb5tq9mykp2w9ry", + "verify": "true" + }, + "影视": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://aysappto.oss-cn-chengdu.aliyuncs.com/qj2.txt", + "key": "sada21321sdq231d", + "iv": "sada21321sdq231d", + "verify": "true" + }, + "数字": { + "muban": "AppGet", + "host": "http://app1-0-0.87333.cc", + "hosturl": "", + "key": "VwsHxkCViDXEExWa", + "iv": "VwsHxkCViDXEExWa", + "verify": "true" + }, + "火锅": { + "muban": "AppGet", + "host": "https://ios.hgyx.vip", + "hosturl": "", + "key": "062dec75d039980e", + "iv": "062dec75d039980e", + "verify": "true" + }, + "五八": { + "muban": "AppGet", + "host": "https://dy.58ys.vip", + "hosturl": "", + "key": "JEWibY1AgWF0V1xx", + "iv": "JEWibY1AgWF0V1xx", + "verify": "true" + }, + "旗星": { + "muban": "AppGet", + "host": "http://ys.qist.top", + "hosturl": "", + "key": "2SWSPFxugBLPPOKo", + "iv": "2SWSPFxugBLPPOKo", + "verify": "true" + }, + "灵虎": { + "muban": "AppGet", + "host": "", + "hosturl": "https://bind.315999.xyz/89.txt", + "key": "#getapp@TMD@2025", + "iv": "#getapp@TMD@2025", + "verify": "true" + }, + "剧梦": { + "muban": "AppGet", + "host": "https://www.jumengwu.com", + "hosturl": "", + "key": "1f0a873caf2550a5", + "iv": "1f0a873caf2550a5", + "verify": "true" + }, + "火狐": { + "muban": "AppGet", + "host": "http://huohu.yihn.cc", + "hosturl": "", + "key": "huohushipingetap", + "iv": "huohushipingetap", + "verify": "true" + }, + "金牌": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://dtqj.ggtvb.cc/dtjp.txt", + "key": "eecbio48dsq131ee", + "iv": "eecbio48dsq131ee", + "verify": "true" + }, + "爱盈": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://aysappto.oss-cn-chengdu.aliyuncs.com/qj3.txt", + "key": "sda1231sasddad21", + "iv": "sda1231sasddad21", + "verify": "true" + }, + "顾我": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://guwozj-1319364746.cos.ap-guangzhou.myqcloud.com/guwo.txt", + "key": "ca94b06ca3c7d80e", + "iv": "ca94b06ca3c7d80e", + "verify": "true" + }, + "爆炸": { + "muban": "AppQiji", + "host": "", + "hosturl": "https://daen-1256234123.cos.ap-shanghai.myqcloud.com/MuQi/mqxh.txt", + "key": "37kj83zs1q16jk6t", + "iv": "37kj83zs1q16jk6t", + "verify": "true" + }, + "橘子": { + "muban": "AppQiji", + "host": "https://juziapp.tpmbt.cn", + "hosturl": "", + "key": "K3h6YvSU8BTUfEcb", + "iv": "K3h6YvSU8BTUfEcb", + "verify": "true" + }, + "丫丫动漫": { + "muban": "AppGet", + "host": "http://tv.yy-fun.cc", + "hosturl": "", + "key": "qkxnwkfjwpcnwycl", + "iv": "qkxnwkfjwpcnwycl", + "verify": "true" + }, + "咕咕动漫": { + "muban": "AppGet", + "host": "https://www.gugu3.com", + "hosturl": "", + "key": "nKfZ8KX6JTNWRzTD", + "iv": "nKfZ8KX6JTNWRzTD", + "verify": "true" + }, + "元咲动漫": { + "muban": "AppGet", + "host": "http://cic.aicg.fun", + "hosturl": "", + "key": "2c4h36abd96se10u", + "iv": "2c4h36abd96se10u", + "verify": "true" + }, + "方舟动漫": { + "muban": "AppGet", + "host": "https://www.cyfz.vip", + "hosturl": "", + "key": "e72cdfd629e8895d", + "iv": "e72cdfd629e8895d", + "verify": "true" } }, "Appmuou": { @@ -40,14 +232,6 @@ "key1": "", "key2": "", "version": "" - }, - "光映视界": { - "host": "", - "hosturl": "https://ymdtsy.lingutv.cn/shark/api.txt", - "key": "IKXRx4M6cB45SNTs", - "key1": "rectangleadsadxa", - "key2": "aassddwwxxllsx1x", - "version": "2.2.0" } } } \ No newline at end of file From 4b7722f4adf411b405de64918e8fc3b4985e801d Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Thu, 15 Jan 2026 15:33:54 +0800 Subject: [PATCH 18/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=85=B7=E6=88=91?= =?UTF-8?q?=E9=9F=B3=E4=B9=90=E7=9B=B8=E5=85=B3=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\351\237\263\344\271\220[\345\220\254].js" | 12 ++++++-- ...\351\237\263\344\271\220[\345\220\254].js" | 29 ++++++++++++++----- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git "a/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" index 766d76fe..1edc387c 100644 --- "a/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" +++ "b/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" @@ -33,8 +33,16 @@ var rule = { let data = JSON.parse(await request(url, { headers: rule.headers })); - let mp3 = data.data.mp3; - return {parse: 0, url: mp3, header: rule.headers}; + let songData = data.data; + return { + parse: 0, + url: songData.mp3, // 播放链接 + header: rule.headers, // 请求头 + lrc: songData.lrc, // 歌词内容 + img: songData.pic, // 封面图片 + title: songData.mname, // 歌名 + singer: songData.sname // 歌手 + }; }, 推荐: "*", 一级: '.mobile-list&&.mobile-list-item;.songname&&Text;.lazyload&&data-src;.authorname&&Text;a&&href', diff --git "a/spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" "b/spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" index 9d1baf95..80c3539f 100644 --- "a/spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" +++ "b/spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" @@ -21,20 +21,35 @@ var rule = { }, class_parse: '.aside-menu-list.channel&&[href*=list];a&&Text;a&&href;.(list.*).htm', play_parse: true, + + // --- 重构的核心部分 --- lazy: $js.toString(() => { + // 1. 将详情页 URL 替换为 API 接口 URL input = input.replace(/play\/(\w+)\.htm/, 'ajax/?act=songinfo&id=$1&lang='); - log(input); - let mp3 = JSON.parse(request(input)).data.mp3; - input = {parse: 0, url: mp3, header: rule.headers}; + + // 2. 发起请求并解析 JSON + let html = request(input); + let json = JSON.parse(html); + let data = json.data; + + // 3. 构造播放对象,包含歌词和元数据 + input = { + parse: 0, + url: data.mp3, // 播放链接 + header: rule.headers, // 请求头 + lrc: data.lrc, // 歌词内容 + img: data.pic, // 封面图片 + title: data.mname, // 歌名 + singer: data.sname // 歌手 + }; }), + // --------------------- + limit: 6, - // 图片来源:'@Referer=https://www.zz123.com/', 推荐: "*", 一级: '.mobile-list&&.mobile-list-item;.songname&&Text;.lazyload&&data-src;.authorname&&Text;a&&href', 二级: '*', - // searchUrl:'/search/?key=**&page=fypage', - // 搜索:'*', searchUrl: '/ajax/?act=search&key=**&lang=', - detailUrl: '/play/fyid.html', + detailUrl: '/play/fyid.html', // 修正:原来是 play/fyid.html,这里保持一致,lazy中正则会匹配 搜索: 'json:data;mname;pic;sname;id', } \ No newline at end of file From c105d0fec92eedb951a939a3d9a55f32d19f1761 Mon Sep 17 00:00:00 2001 From: Taois Date: Thu, 15 Jan 2026 19:42:19 +0800 Subject: [PATCH 19/99] =?UTF-8?q?feat:=20=E5=90=88=E5=B9=B6=E7=A7=8B?= =?UTF-8?q?=E7=A7=8B=E6=8F=90=E4=BE=9B=E7=9A=84=E6=89=AB=E7=A0=81=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E7=95=8C=E9=9D=A2=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/cookie-butler/index.html | 63 ++++++++++++++++--- apps/cookie-butler/static/js/cookie.js | 2 +- apps/cookie-butler/static/js/jsencrypt.min.js | 1 + 3 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 apps/cookie-butler/static/js/jsencrypt.min.js diff --git a/apps/cookie-butler/index.html b/apps/cookie-butler/index.html index 51942ecc..ca9d936d 100644 --- a/apps/cookie-butler/index.html +++ b/apps/cookie-butler/index.html @@ -12,6 +12,7 @@ +
    @@ -19,10 +20,13 @@ @@ -93,28 +97,67 @@ const textValue = document.getElementById("cookie-res").value || ''; const active_name = activeLi.textContent.trim(); const active_key = activeLi.getAttribute('data-platform').trim(); - const save_key = active_key === 'ali' ? active_key + '_token' : active_key + '_cookie'; + let save_key = '' + if (/ali|pikpak/.test(active_key)) { + save_key = active_key + '_token' + } else { + save_key = active_key + '_cookie'; + } + console.log(`准备入库cookie:${active_name} ${save_key},值为:${textValue}`); const cookie_auth_code = prompt('cookie入库功能需要管理员授权码,请你正确输入后继续'); if (cookie_auth_code) { - // 使用 axios 发送 POST 请求 - axios.post('/admin/cookie-set', { - cookie_auth_code: cookie_auth_code, - key: save_key, - value: textValue.trim().replaceAll('\n', '') - }) - .then(response => { + if (save_key.includes('pikpak')) { + // 使用 axios 发送 POST 请求 + axios.post('/admin/cookie-set', { + cookie_auth_code: cookie_auth_code, + key: save_key, + value: textValue.split(';')[0].trim().replaceAll('\n', '') + }).then(response => { if (response.data.success) { alert(`Cookie 入库成功:${active_name} (${save_key})`); } else { alert(`入库失败:${response.data.message}`); } - }) - .catch(error => { + }).catch(error => { + console.error('请求失败:', error); + alert(`入库失败,服务器出现问题,请稍后再试。\n${error.response.data.message}`); + }); + axios.post('/admin/cookie-set', { + cookie_auth_code: cookie_auth_code, + key: save_key.replace('token', 'refresh_token'), + value: textValue.split(';')[1].trim().replaceAll('\n', '') + }).then(response => { + if (response.data.success) { + alert(`Cookie 入库成功:${active_name} (${save_key.replace('token', 'refresh_token')})`); + } else { + alert(`入库失败:${response.data.message}`); + } + }).catch(error => { console.error('请求失败:', error); alert(`入库失败,服务器出现问题,请稍后再试。\n${error.response.data.message}`); }); + } else { + // 使用 axios 发送 POST 请求 + axios.post('/admin/cookie-set', { + cookie_auth_code: cookie_auth_code, + key: save_key, + value: textValue.trim().replaceAll('\n', '') + }) + .then(response => { + if (response.data.success) { + alert(`Cookie 入库成功:${active_name} (${save_key})`); + } else { + alert(`入库失败:${response.data.message}`); + } + }) + .catch(error => { + console.error('请求失败:', error); + alert(`入库失败,服务器出现问题,请稍后再试。\n${error.response.data.message}`); + }); + } + } } else { alert('至少选中一个cookie入库项目'); diff --git a/apps/cookie-butler/static/js/cookie.js b/apps/cookie-butler/static/js/cookie.js index bff8f94a..f01be452 100644 --- a/apps/cookie-butler/static/js/cookie.js +++ b/apps/cookie-butler/static/js/cookie.js @@ -20,7 +20,7 @@ function showToast(message, type = 'success') { // 初始化页面 async function initializePage() { // 加载cookie - const platforms = ['ali', 'quark', 'uc', 'uc_token', 'bili', 'baidu']; + const platforms = ['ali', 'quark', 'quark_token', 'uc', 'uc_token', 'bili', 'yun', 'baidu', 'pikpak']; // 绑定按钮事件 platforms.forEach(platform => { diff --git a/apps/cookie-butler/static/js/jsencrypt.min.js b/apps/cookie-butler/static/js/jsencrypt.min.js new file mode 100644 index 00000000..27c29d5e --- /dev/null +++ b/apps/cookie-butler/static/js/jsencrypt.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.JSEncrypt={})}(this,function(t){"use strict";var e="0123456789abcdefghijklmnopqrstuvwxyz";function a(t){return e.charAt(t)}function i(t,e){return t&e}function u(t,e){return t|e}function r(t,e){return t^e}function n(t,e){return t&~e}function s(t){if(0==t)return-1;var e=0;return 0==(65535&t)&&(t>>=16,e+=16),0==(255&t)&&(t>>=8,e+=8),0==(15&t)&&(t>>=4,e+=4),0==(3&t)&&(t>>=2,e+=2),0==(1&t)&&++e,e}function o(t){for(var e=0;0!=t;)t&=t-1,++e;return e}var h="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function c(t){var e,i,r="";for(e=0;e+3<=t.length;e+=3)i=parseInt(t.substring(e,e+3),16),r+=h.charAt(i>>6)+h.charAt(63&i);for(e+1==t.length?(i=parseInt(t.substring(e,e+1),16),r+=h.charAt(i<<2)):e+2==t.length&&(i=parseInt(t.substring(e,e+2),16),r+=h.charAt(i>>2)+h.charAt((3&i)<<4));0<(3&r.length);)r+="=";return r}function f(t){var e,i="",r=0,n=0;for(e=0;e>2),n=3&s,r=1):1==r?(i+=a(n<<2|s>>4),n=15&s,r=2):2==r?(i+=a(n),i+=a(s>>2),n=3&s,r=3):(i+=a(n<<2|s>>4),i+=a(15&s),r=0))}return 1==r&&(i+=a(n<<2)),i}var l,p=function(t,e){return(p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var i in e)e.hasOwnProperty(i)&&(t[i]=e[i])})(t,e)};var g,d=function(t){var e;if(void 0===l){var i="0123456789ABCDEF",r=" \f\n\r\t \u2028\u2029";for(l={},e=0;e<16;++e)l[i.charAt(e)]=e;for(i=i.toLowerCase(),e=10;e<16;++e)l[i.charAt(e)]=e;for(e=0;e>16,r[r.length]=n>>8&255,r[r.length]=255&n,s=n=0):n<<=6}}switch(s){case 1:throw new Error("Base64 encoding incomplete: at least 2 bits missing");case 2:r[r.length]=n>>10;break;case 3:r[r.length]=n>>16,r[r.length]=n>>8&255}return r},re:/-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,unarmor:function(t){var e=v.re.exec(t);if(e)if(e[1])t=e[1];else{if(!e[2])throw new Error("RegExp out of sync");t=e[2]}return v.decode(t)}},m=1e13,y=function(){function t(t){this.buf=[+t||0]}return t.prototype.mulAdd=function(t,e){var i,r,n=this.buf,s=n.length;for(i=0;ie&&(t=t.substring(0,e)+b),t}var w,D=function(){function i(t,e){this.hexDigits="0123456789ABCDEF",t instanceof i?(this.enc=t.enc,this.pos=t.pos):(this.enc=t,this.pos=e)}return i.prototype.get=function(t){if(void 0===t&&(t=this.pos++),t>=this.enc.length)throw new Error("Requesting byte offset "+t+" on a stream of length "+this.enc.length);return"string"==typeof this.enc?this.enc.charCodeAt(t):this.enc[t]},i.prototype.hexByte=function(t){return this.hexDigits.charAt(t>>4&15)+this.hexDigits.charAt(15&t)},i.prototype.hexDump=function(t,e,i){for(var r="",n=t;n>u&1?"1":"0";if(s.length>i)return n+E(s,i)}return n+s},i.prototype.parseOctetString=function(t,e,i){if(this.isASCII(t,e))return E(this.parseStringISO(t,e),i);var r=e-t,n="("+r+" byte)\n";(i/=2)i)return E(r,i);n=new y,s=0}}return 0>6,this.tagConstructed=0!=(32&e),this.tagNumber=31&e,31==this.tagNumber){for(var i=new y;e=t.get(),i.mulAdd(128,127&e),128&e;);this.tagNumber=i.simplify()}}return t.prototype.isUniversal=function(){return 0===this.tagClass},t.prototype.isEOC=function(){return 0===this.tagClass&&0===this.tagNumber},t}(),B=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],A=(1<<26)/B[B.length-1],O=function(){function b(t,e,i){null!=t&&("number"==typeof t?this.fromNumber(t,e,i):null==e&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,e))}return b.prototype.toString=function(t){if(this.s<0)return"-"+this.negate().toString(t);var e;if(16==t)e=4;else if(8==t)e=3;else if(2==t)e=1;else if(32==t)e=5;else{if(4!=t)return this.toRadix(t);e=2}var i,r=(1<>h)&&(n=!0,s=a(i));0<=o;)h>(h+=this.DB-e)):(i=this[o]>>(h-=e)&r,h<=0&&(h+=this.DB,--o)),0>24},b.prototype.shortValue=function(){return 0==this.t?this.s:this[0]<<16>>16},b.prototype.signum=function(){return this.s<0?-1:this.t<=0||1==this.t&&this[0]<=0?0:1},b.prototype.toByteArray=function(){var t=this.t,e=[];e[0]=this.s;var i,r=this.DB-t*this.DB%8,n=0;if(0>r)!=(this.s&this.DM)>>r&&(e[n++]=i|this.s<>(r+=this.DB-8)):(i=this[t]>>(r-=8)&255,r<=0&&(r+=this.DB,--t)),0!=(128&i)&&(i|=-256),0==n&&(128&this.s)!=(128&i)&&++n,(0=this.t?0!=this.s:0!=(this[e]&1<>n-a&u:(f=(t[p]&(1<>this.DB+n-a)),h=i;0==(1&f);)f>>=1,--h;if((n-=h)<0&&(n+=this.DB,--p),g)o[f].copyTo(s),g=!1;else{for(;1this.DB?(this[this.t-1]|=(o&(1<>this.DB-s):this[this.t-1]|=o<=this.DB&&(s-=this.DB))}8==i&&0!=(128&+t[0])&&(this.s=-1,0>r|o,o=(this[h]&n)<=this.t)e.t=0;else{var r=t%this.DB,n=this.DB-r,s=(1<>r;for(var o=i+1;o>r;0>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;i>=this.DB;r-=t.s}e.s=r<0?-1:0,r<-1?e[i++]=this.DV+r:0=e.DV&&(t[i+e.t]-=e.DV,t[i+e.t+1]=1)}0>this.F2:0),l=this.FV/f,p=(1<=i&&(this.dMultiply(r),this.dAddOffset(o,0),o=s=0))}0t&&this.subTo(b.ONE.shiftLeft(t-1),this);else{var r=[],n=7&t;r.length=1+(t>>3),e.nextBytes(r),0>=this.DB;if(t.t>=this.DB;r+=this.s}else{for(r+=this.s;i>=this.DB;r+=t.s}e.s=r<0?-1:0,0=this.DV;)this[e]-=this.DV,++e>=this.t&&(this[this.t++]=0),++this[e]}},b.prototype.multiplyLowerTo=function(t,e,i){var r=Math.min(this.t+t.t,e);for(i.s=0,i.t=r;0>1)&&(t=B.length);for(var n=M(),s=0;st&&n.subTo(b.ONE.shiftLeft(t-1),n),n.isProbablePrime(e)?setTimeout(function(){r()},0):setTimeout(s,0)};setTimeout(s,0)}else{var o=[],h=7&t;o.length=1+(t>>3),e.nextBytes(o),0>15,this.um=(1<>15)*this.mpl&this.um)<<15)&t.DM;for(t[i=e+this.m.t]+=this.m.am(0,r,t,e,0,this.m.t);t[i]>=t.DV;)t[i]-=t.DV,t[++i]++}t.clamp(),t.drShiftTo(this.m.t,t),0<=t.compareTo(this.m)&&t.subTo(this.m,t)},t.prototype.mulTo=function(t,e,i){t.multiplyTo(e,i),this.reduce(i)},t.prototype.sqrTo=function(t,e){t.squareTo(e),this.reduce(e)},t}(),P=function(){function t(t){this.m=t,this.r2=M(),this.q3=M(),O.ONE.dlShiftTo(2*t.t,this.r2),this.mu=this.r2.divide(t)}return t.prototype.convert=function(t){if(t.s<0||t.t>2*this.m.t)return t.mod(this.m);if(t.compareTo(this.m)<0)return t;var e=M();return t.copyTo(e),this.reduce(e),e},t.prototype.revert=function(t){return t},t.prototype.reduce=function(t){for(t.drShiftTo(this.m.t-1,this.r2),t.t>this.m.t+1&&(t.t=this.m.t+1,t.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);t.compareTo(this.r2)<0;)t.dAddOffset(1,this.m.t+1);for(t.subTo(this.r2,t);0<=t.compareTo(this.m);)t.subTo(this.m,t)},t.prototype.mulTo=function(t,e,i){t.multiplyTo(e,i),this.reduce(i)},t.prototype.sqrTo=function(t,e){t.squareTo(e),this.reduce(e)},t}();function M(){return new O(null)}function q(t,e){return new O(t,e)}"Microsoft Internet Explorer"==navigator.appName?(O.prototype.am=function(t,e,i,r,n,s){for(var o=32767&e,h=e>>15;0<=--s;){var a=32767&this[t],u=this[t++]>>15,c=h*a+u*o;n=((a=o*a+((32767&c)<<15)+i[r]+(1073741823&n))>>>30)+(c>>>15)+h*u+(n>>>30),i[r++]=1073741823&a}return n},w=30):"Netscape"!=navigator.appName?(O.prototype.am=function(t,e,i,r,n,s){for(;0<=--s;){var o=e*this[t++]+i[r]+n;n=Math.floor(o/67108864),i[r++]=67108863&o}return n},w=26):(O.prototype.am=function(t,e,i,r,n,s){for(var o=16383&e,h=e>>14;0<=--s;){var a=16383&this[t],u=this[t++]>>14,c=h*a+u*o;n=((a=o*a+((16383&c)<<14)+i[r]+n)>>28)+(c>>14)+h*u,i[r++]=268435455&a}return n},w=28),O.prototype.DB=w,O.prototype.DM=(1<>>16)&&(t=e,i+=16),0!=(e=t>>8)&&(t=e,i+=8),0!=(e=t>>4)&&(t=e,i+=4),0!=(e=t>>2)&&(t=e,i+=2),0!=(e=t>>1)&&(t=e,i+=1),i}O.ZERO=F(0),O.ONE=F(1);var K=function(){function t(){this.i=0,this.j=0,this.S=[]}return t.prototype.init=function(t){var e,i,r;for(e=0;e<256;++e)this.S[e]=e;for(e=i=0;e<256;++e)i=i+this.S[e]+t[e%t.length]&255,r=this.S[e],this.S[e]=this.S[i],this.S[i]=r;this.i=0,this.j=0},t.prototype.next=function(){var t;return this.i=this.i+1&255,this.j=this.j+this.S[this.i]&255,t=this.S[this.i],this.S[this.i]=this.S[this.j],this.S[this.j]=t,this.S[t+this.S[this.i]&255]},t}();var k,_,z=256,Z=null;if(null==Z){Z=[];var G=void(_=0);if(window.crypto&&window.crypto.getRandomValues){var $=new Uint32Array(256);for(window.crypto.getRandomValues($),G=0;G<$.length;++G)Z[_++]=255&$[G]}var Y=function(t){if(this.count=this.count||0,256<=this.count||z<=_)window.removeEventListener?window.removeEventListener("mousemove",Y,!1):window.detachEvent&&window.detachEvent("onmousemove",Y);else try{var e=t.x+t.y;Z[_++]=255&e,this.count+=1}catch(t){}};window.addEventListener?window.addEventListener("mousemove",Y,!1):window.attachEvent&&window.attachEvent("onmousemove",Y)}function J(){if(null==k){for(k=new K;_>6|192):(i[--e]=63&n|128,i[--e]=n>>6&63|128,i[--e]=n>>12|224)}i[--e]=0;for(var s=new X,o=[];2>3);if(null==e)return null;var i=this.doPublic(e);if(null==i)return null;var r=i.toString(16);return 0==(1&r.length)?r:"0"+r},t.prototype.setPrivate=function(t,e,i){null!=t&&null!=e&&0>1;this.e=parseInt(e,16);for(var n=new O(e,16);;){for(;this.p=new O(t-r,1,i),0!=this.p.subtract(O.ONE).gcd(n).compareTo(O.ONE)||!this.p.isProbablePrime(10););for(;this.q=new O(r,1,i),0!=this.q.subtract(O.ONE).gcd(n).compareTo(O.ONE)||!this.q.isProbablePrime(10););if(this.p.compareTo(this.q)<=0){var s=this.p;this.p=this.q,this.q=s}var o=this.p.subtract(O.ONE),h=this.q.subtract(O.ONE),a=o.multiply(h);if(0==a.gcd(n).compareTo(O.ONE)){this.n=this.p.multiply(this.q),this.d=n.modInverse(a),this.dmp1=this.d.mod(o),this.dmq1=this.d.mod(h),this.coeff=this.q.modInverse(this.p);break}}},t.prototype.decrypt=function(t){var e=q(t,16),i=this.doPrivate(e);return null==i?null:function(t,e){var i=t.toByteArray(),r=0;for(;r=i.length)return null;var n="";for(;++r>3)},t.prototype.generateAsync=function(t,e,n){var s=new X,o=t>>1;this.e=parseInt(e,16);var h=new O(e,16),a=this,u=function(){var e=function(){if(a.p.compareTo(a.q)<=0){var t=a.p;a.p=a.q,a.q=t}var e=a.p.subtract(O.ONE),i=a.q.subtract(O.ONE),r=e.multiply(i);0==r.gcd(h).compareTo(O.ONE)?(a.n=a.p.multiply(a.q),a.d=h.modInverse(r),a.dmp1=a.d.mod(e),a.dmq1=a.d.mod(i),a.coeff=a.q.modInverse(a.p),setTimeout(function(){n()},0)):setTimeout(u,0)},i=function(){a.q=M(),a.q.fromNumberAsync(o,1,s,function(){a.q.subtract(O.ONE).gcda(h,function(t){0==t.compareTo(O.ONE)&&a.q.isProbablePrime(10)?setTimeout(e,0):setTimeout(i,0)})})},r=function(){a.p=M(),a.p.fromNumberAsync(t-o,1,s,function(){a.p.subtract(O.ONE).gcda(h,function(t){0==t.compareTo(O.ONE)&&a.p.isProbablePrime(10)?setTimeout(i,0):setTimeout(r,0)})})};setTimeout(r,0)};setTimeout(u,0)},t.prototype.sign=function(t,e,i){var r=function(t,e){if(e=e?t:new Array(e-t.length+1).join("0")+t},this.getString=function(){return this.s},this.setString=function(t){this.hTLV=null,this.isModified=!0,this.s=t,this.hV=stohex(t)},this.setByDateValue=function(t,e,i,r,n,s){var o=new Date(Date.UTC(t,e-1,i,r,n,s,0));this.setByDate(o)},this.getFreshValueHex=function(){return this.hV}},tt.lang.extend(et.asn1.DERAbstractTime,et.asn1.ASN1Object),et.asn1.DERAbstractStructured=function(t){et.asn1.DERAbstractString.superclass.constructor.call(this),this.setByASN1ObjectArray=function(t){this.hTLV=null,this.isModified=!0,this.asn1Array=t},this.appendASN1Object=function(t){this.hTLV=null,this.isModified=!0,this.asn1Array.push(t)},this.asn1Array=new Array,void 0!==t&&void 0!==t.array&&(this.asn1Array=t.array)},tt.lang.extend(et.asn1.DERAbstractStructured,et.asn1.ASN1Object),et.asn1.DERBoolean=function(){et.asn1.DERBoolean.superclass.constructor.call(this),this.hT="01",this.hTLV="0101ff"},tt.lang.extend(et.asn1.DERBoolean,et.asn1.ASN1Object),et.asn1.DERInteger=function(t){et.asn1.DERInteger.superclass.constructor.call(this),this.hT="02",this.setByBigInteger=function(t){this.hTLV=null,this.isModified=!0,this.hV=et.asn1.ASN1Util.bigIntToMinTwosComplementsHex(t)},this.setByInteger=function(t){var e=new O(String(t),10);this.setByBigInteger(e)},this.setValueHex=function(t){this.hV=t},this.getFreshValueHex=function(){return this.hV},void 0!==t&&(void 0!==t.bigint?this.setByBigInteger(t.bigint):void 0!==t.int?this.setByInteger(t.int):"number"==typeof t?this.setByInteger(t):void 0!==t.hex&&this.setValueHex(t.hex))},tt.lang.extend(et.asn1.DERInteger,et.asn1.ASN1Object),et.asn1.DERBitString=function(t){if(void 0!==t&&void 0!==t.obj){var e=et.asn1.ASN1Util.newObject(t.obj);t.hex="00"+e.getEncodedHex()}et.asn1.DERBitString.superclass.constructor.call(this),this.hT="03",this.setHexValueIncludingUnusedBits=function(t){this.hTLV=null,this.isModified=!0,this.hV=t},this.setUnusedBitsAndHexValue=function(t,e){if(t<0||7 Date: Thu, 15 Jan 2026 23:42:48 +0800 Subject: [PATCH 20/99] =?UTF-8?q?add:=20=E6=96=B0=E5=A2=9E=E7=95=AA?= =?UTF-8?q?=E8=8C=84=E6=BC=AB=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\260\217\350\257\264[\344\271\246].js" | 2 +- ...\346\274\253\347\224\273[\347\224\273].js" | 112 ++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 "spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" diff --git "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" index b659fa25..53cd0233 100644 --- "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" @@ -31,7 +31,7 @@ var rule = { homeUrl: 'https://fanqienovel.com/api/author/book/category_list/v0/', url: '/api/author/library/book_list/v0/?page_count=18&page_index=(fypage-1)&gender=1&category_id=fyclass&creation_status=-1&word_count=-1&book_type=-1&sort=0#fyfilter', // searchUrl: fqweb_host + '/search?query=**&page=fypage', - searchUrl: fqweb_host + '/api/search?key=**&tab_type=3&offset=0&page=fypage', + searchUrl: fqweb_host + '/api/search?key=**&tab_type=3&offset=((fypage-1)*10)', searchable: 2, quickSearch: 0, filterable: 1, diff --git "a/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" "b/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" new file mode 100644 index 00000000..230432e8 --- /dev/null +++ "b/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" @@ -0,0 +1,112 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 0, + title: '番茄漫画', + '类型': '漫画', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '漫画', + title: '番茄漫画', + host: 'https://qkfqapi.vv9v.cn', + url: '', + searchUrl: '/api/search?key=**&tab_type=8&offset=((fypage-1)*10)', + detailUrl: '/api/detail?book_id=fyid', + headers: {'User-Agent': 'UC_UA'}, + searchable: 1, + quickSearch: 0, + filterable: 0, + double: true, + play_parse: true, + limit: 12, + // class_parse: async function () { + // let {input, pdfa, pdfh, pd} = this; + // return {} + // }, + lazy: async function () { + let {input, pdfa, pdfh} = this; + let title = input.split('@')[1]; + input = input.split('@')[0]; + let content_url = `https://qkfqapi.vv9v.cn/api/content?tab=漫画&item_id=${input}&show_html=0`; // 正文获取接口 + let jsonStr = await request(content_url); + let images = jsonStr.parseX.data.images; + images = pdfa(images, 'img'); + let pics = [] + for (let img of images) { + let pic = pdfh(img, 'img&&src'); + pics.push(pic); + } + return {parse: 0, url: 'pics://' + pics.join('&&')} + }, + 推荐: async function () { + return [{ + vod_id: 'only_search', + vod_name: '纯搜索源哦!', + vod_tag: 'action', + vod_pic: this.publicUrl + '/images/icon_cookie/搜索.jpg' + }]; + }, + 一级: async function () { + return []; + }, + 二级: async function () { + let {input, orId} = this; + // log('input', input); + // log('orId', orId); + let html = await request(input); + let json = JSON.parse(html); + let data = json.data.data; + let VOD = {}; + VOD.vod_name = data.book_name; + VOD.type_name = data.category; + VOD.vod_pic = data.thumb_url; + VOD.vod_content = data.abstract; + VOD.vod_remarks = data.sub_info; + VOD.vod_year = ''; + VOD.vod_area = ''; + VOD.vod_actor = ''; + VOD.vod_director = data.author; + VOD.vod_play_from = '番茄漫画'; + let jsonStr = await request(`https://qkfqapi.vv9v.cn/api/book?book_id=${orId}`); + let book_info = jsonStr.parseX.data.data; + let list = book_info.chapterListWithVolume.flat(); + let urls = []; + list.forEach((it, index) => { + urls.push(it.title + '$' + it.itemId + '@' + it.title); + }); + VOD.vod_play_url = urls.join('#'); + return VOD + }, + 搜索: async function () { + let {input, MY_PAGE} = this; + // if (Number(MY_PAGE) > 1) { + // return [] + // } + print(input) + let html = await request(input); + let json = JSON.parse(html); + let data = json.data.search_tabs[3].data; + let d = []; + for (let it of data.filter(i => i.book_data)) { + let book = it.book_data[0]; + // console.log(book) + d.push({ + title: book.book_name, + url: book.book_id, + desc: book.author, + content: book.book_abstract || book.abstract, + pic_url: book.thumb_url + }); + } + return setResult(d) + }, + action: async function (action, value) { + if (action === 'only_search') { + return '此源为纯搜索源,你直接全局搜索这个源或者使用此页面的源内搜索就好了' + } + } +} \ No newline at end of file From b395b4dbce81762afbcb17730b79f0f9440cdcfb Mon Sep 17 00:00:00 2001 From: Taois Date: Thu, 15 Jan 2026 23:59:49 +0800 Subject: [PATCH 21/99] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E5=87=A0=E4=B8=AA?= =?UTF-8?q?=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...252\350\214\204\345\260\217\350\257\264[\344\271\246].js" | 5 +++++ 1 file changed, 5 insertions(+) diff --git "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" index 53cd0233..12279717 100644 --- "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" @@ -22,6 +22,11 @@ const {requestHtml} = $.require('./_lib.request.js'); // const fqweb_host = 'http://fqweb.jsj66.com'; // const fqweb_host = 'http://fanqie.mduge.com'; const fqweb_host = 'https://qkfqapi.vv9v.cn'; +// const fqweb_host = 'http://101.35.133.34:5000/docs'; //备选 +// const fqweb_host = 'http://103.236.91.147:9999/docs'; //备选 +// const fqweb_host = 'http://47.108.80.161:5005/docs'; //备选 +// const fqweb_host = 'http://140.143.165.56:9999/docs'; //备选 +// const fqweb_host = 'http://8.148.83.169:22222/docs'; //备选 var rule = { 类型: '小说', From dd58dbd14b89e0a333943535c5261a5301ee97fe Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 00:11:34 +0800 Subject: [PATCH 22/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/map.txt | 4 - ...\346\235\277\351\205\215\347\275\256.json" | 8 - public/sub/order_common.example.html | 4 +- ...\350\257\273\344\271\246[\344\271\246].js" | 155 +++++++++++++++++ ...\345\212\251\346\211\213[\344\271\246].js" | 160 ++++++++++++++++++ 5 files changed, 318 insertions(+), 13 deletions(-) create mode 100644 "spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" create mode 100644 "spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" diff --git a/config/map.txt b/config/map.txt index a6603726..13760290 100644 --- a/config/map.txt +++ b/config/map.txt @@ -38,7 +38,6 @@ AppFei@@https://ysa.yy-fun.cc/feiapp@@森林动漫[AF] AppGet@@{"host":"https://snysw.xyz/mf4kzs327.txt","key":"1234567887654321"}@@魔方[AG¹] AppGet@@{"host":"https://gitee.com/wmmoliill/wimg/raw/master/img/bk/9.txt","key":"88689667dce61725"}@@茉莉[AG¹] AppGet@@{"host":"http://ys.qist.top","key":"2SWSPFxugBLPPOKo"}@@旗星[AG¹] -AppGet@@{"host":"https://api1.bffree.cn","key":"2015692015692015"}@@橘子[AG¹] AppGet@@{"host":"https://dy.58ys.vip","key":"JEWibY1AgWF0V1xx"}@@五八[AG¹] AppGet@@{"host":"https://mac.555618.xyz","key":"#getapp@TMD@2025"}@@玲珑[AG¹] AppGet@@{"host":"https://app.omofun1.top","key":"66dc309cbeeca454"}@@OMOfun[AG¹] @@ -50,16 +49,13 @@ AppSk@@{"host":"https://sk.xiaoyaoys.top/skkkkkkk.txt","key":"ygcnbcczduwydmrs", AppV6@@{"api":"http://yjyi.juyongjiu.com/icciu_api.php/v1.vod","datasignkey":"6QQNUsP3PkD2ajJCPCY8","apisignkey":"lvdoutv-1.0.0"}@@剧永久[AV⁶] AppV6@@http://jxfmax.juxiafan.com/icciu_api.php/v1.vod@@剧下饭[AV⁶] AppToV5@@http://118.89.203.120:8762@@番喜[ATV⁵] -AppToV5@@http://111.173.114.61:8762@@爱看剧Fax[ATV⁵] AppToV5@@http://38.55.237.41:8762@@皮皮虾[ATV⁵] -AppV2²@@https://www.heli888.cc@@河狸![AV²] AppV2²@@http://38.47.213.61:41271@@闪影[AV²] AppV2²@@http://v.lnhaozhenjin.cn@@好震惊[AV²] AppV2²@@http://jxfmax.juxiafan.com@@剧下饭[AV²] AppV1@@http://ziyuncms.feifan12.xyz/api.php@@紫云[AV¹] getapp3.4.4@@{"host":"https://staraugust123456.oss-cn-hangzhou.aliyuncs.com/2.txt","datakey":"staraugust123456","api":2}@@云云[AG³] getapp3.4.4@@{"host":"https://jingyu4k-1312635929.cos.ap-nanjing.myqcloud.com/1.json","datakey":"AAdgrdghjfgswerA","api":2}@@鲸鱼影视[AG³] -getapp3.4.4@@{"host":"https://www.guahd.com/1.txt","key":"f2A7D4B9E8C16531"}@@瓜萌[AG³] getapp3.4.4@@{"host":"https://99.jl8.top/1.txt","key":"xnybssspqtwotuwj"}@@七月[AG³] getapp3.4.4@@{"host":"http://tvb.yy-fun.cc","key":"jcTz6Jda2aKrH8Tk"}@@掌上追剧[AG³] AppHs@@{"host":"https://dy.jmzp.net.cn","app_id":"shiguang","deviceid":"","versionCode":"10000","UMENG_CHANNEL":"guan"}@@拾光视频[Hs] diff --git "a/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" "b/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" index acca5464..c78b8a10 100644 --- "a/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" +++ "b/json/App\346\250\241\346\235\277\351\205\215\347\275\256.json" @@ -176,14 +176,6 @@ "iv": "37kj83zs1q16jk6t", "verify": "true" }, - "橘子": { - "muban": "AppQiji", - "host": "https://juziapp.tpmbt.cn", - "hosturl": "", - "key": "K3h6YvSU8BTUfEcb", - "iv": "K3h6YvSU8BTUfEcb", - "verify": "true" - }, "丫丫动漫": { "muban": "AppGet", "host": "http://tv.yy-fun.cc", diff --git a/public/sub/order_common.example.html b/public/sub/order_common.example.html index 33cf163c..a82a7930 100644 --- a/public/sub/order_common.example.html +++ b/public/sub/order_common.example.html @@ -1,16 +1,18 @@ 设置中心 番茄小说 -大象影视 腾云驾雾 央视大全 IPTV [优] [盘] [漫] +[短] [官] [听] +[书] [搜] DS cat +DR2 hipy 推送 diff --git "a/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" new file mode 100644 index 00000000..86b8b485 --- /dev/null +++ "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" @@ -0,0 +1,155 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 1, + title: '去读书[书]', + author: 'EylinSir', + '类型': '小说', + logo: 'http://www.qudushu.com/favicon.ico', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '小说', + author: 'EylinSir', + title: '去读书[书]', + host: 'http://www.qudushu.com', + url: '/book/fyclass/0/fypage.html', + logo: 'http://www.qudushu.com/favicon.ico', + class_name: '玄幻魔法&武侠修真&都市言情&历史军事&穿越架空&游戏竞技', + class_url: 'sort1&sort2&sort3&sort4&sort5&sort6', + searchUrl: '/modules/article/search.php?q=**', + searchable: 1, + quickSearch: 1, + filterable: 0, + timeout: 10000, + play_parse: true, + headers: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36' + }, + request: async function (url, obj) { + obj = obj || {}; + try { + const response = await _fetch(url, { + method: obj.method || 'GET', + headers: obj.headers || this.headers + }); + return response.text(); + } catch (err) { + return ''; + } + }, + + 一级: async function () { + let {input, pdfa, pdfh, pd} = this; + let url = input.startsWith('http') ? input : this.host + '/book/' + input + '/0/1.html'; + let html = await this.request(url); + let d = []; + let items = pdfa(html, '.blockcontent .c_row') || pdfa(html, '.c_row') || []; + for (let item of items) { + let title = pdfh(item, '.c_subject a:eq(1)&&Text'); + let itemUrl = pd(item, '.c_subject a:eq(1)&&href'); + if (!title || !itemUrl) continue; + let remarks = pdfh(item, '.c_tag span:eq(1)&&Text') || ''; + let pic = pd(item, 'img&&src') || ''; + let content = pdfh(item, '.c_description&&Text') || ''; + d.push({ + title: title, + url: itemUrl, + desc: remarks, + pic_url: pic, + content: content, + }); + } + return setResult(d); + }, + + 二级: async function () { + let {input, pdfa, pdfh, pd} = this; + let html = await this.request(input); + let VOD = {}; + VOD.vod_name = pdfh(html, '[property="og:novel:book_name"]&&content') || ''; + VOD.type_name = ''; + VOD.vod_pic = pd(html, '.divbox.cf img&&src') || ''; + VOD.vod_content = pdfh(html, '.tabcontent .tabvalue:eq(0)&&Text') || ''; + VOD.vod_remarks = pdfh(html, 'h3 a&&Text') || ''; + VOD.vod_year = ''; + VOD.vod_area = ''; + VOD.vod_actor = pdfh(html, '[property="og:novel:author"]&&content') || ''; + VOD.vod_director = VOD.vod_actor; + VOD.vod_play_from = '去读书网'; + let toc_url = pd(html, 'a:contains(点击阅读)&&href') || ''; + if (toc_url && !toc_url.startsWith('http')) { + toc_url = this.host + toc_url; + } + let toc_html = toc_url ? await this.request(toc_url) : ''; + let chapters = []; + let chapterItems = pdfa(toc_html, '.index li') || []; + for (let chapter of chapterItems) { + let title = pdfh(chapter, 'a&&Text'); + let chapter_url = pd(chapter, 'a&&href'); + if (!title || !chapter_url) continue; + if (!chapter_url.startsWith('http')) { + chapter_url = this.host + chapter_url; + } + chapters.push(title + '$' + chapter_url); + } + VOD.vod_play_url = chapters.join('#'); + return VOD; + }, + + 搜索: async function () { + let {KEY, pdfa, pdfh, pd} = this; + let url = this.host + this.searchUrl.replace('**', encodeURIComponent(KEY)); + let html = await this.request(url); + if (!html) { + url = this.host + '/modules/article/search.php?q=' + encodeURIComponent(KEY); + html = await this.request(url); + } + let d = []; + let items = pdfa(html, '#jieqi_page_contents .c_row') || []; + for (let item of items) { + let title = pdfh(item, '.c_subject a&&Text'); + let itemUrl = pd(item, '.c_subject a&&href'); + if (!title || !itemUrl) continue; + itemUrl = itemUrl.startsWith('http') ? itemUrl : this.host + itemUrl; + let pic = pd(item, 'img&&src') || ''; + pic = pic.startsWith('http') ? pic : this.host + pic; + d.push({ + title: title, + url: itemUrl, + desc: pdfh(item, '.c_tag span:eq(1)&&Text') || '', + pic_url: pic, + content: '', + }); + } + return setResult(d); + }, + + lazy: async function () { + let {input, pdfh} = this; + let html = await this.request(input); + let title = pdfh(html, 'h1&&Text') || ''; + let content = pdfh(html, '#acontent&&Html') || ''; + if (content) { + content = content.replace(/]*?>.*?<\/script>/gs, '') + .replace(/<\/p>/g, '\n\n') + .replace(/]*?>/g, '\n') + .replace(/<[^>]*?>/g, '') + .replace(/去读书推荐各位书友阅读:.*|去读书 www\.qudushu\.la|如果您中途有事离开,请按.*以便以后接着观看!/g, '') + .replace(/[()]/g, '') + .replace(/ /g, ' ') + .replace(/[ \t]+/g, ' ') + .replace(/\n[ \t]+|[ \t]+\n/g, '\n') + .replace(/\n+/g, '\n\n') + .trim(); + } + return { + parse: 0, + url: 'novel://' + JSON.stringify({title, content}), + js: '' + }; + } +}; diff --git "a/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" new file mode 100644 index 00000000..40f61d11 --- /dev/null +++ "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" @@ -0,0 +1,160 @@ +var rule = { + 类型: '小说', + author: 'EylinSir', + title: '阅读助手[书]', + desc: '阅读助手小说源', + host: 'https://api-bc.wtzw.com', + homeUrl: 'https://api-bc.wtzw.com', + url: '/api/v4/category/get-list?gender=fyclass&category_id=fyfilter&need_filters=1&page=fypage&need_category=1', + class_name: '男生&女生&出版', + class_url: '1&2&3', + searchUrl: '/api/v5/search/words?gender=3&imei_ip=2937357107&page=fypage&wd=**', + searchable: 2, + quickSearch: 0, + filterable: 1, + filter: { + "1": [{key: "type", name: "类型", value: [{"n":"玄幻奇幻","v":"202"},{"n":"都市人生","v":"203"},{"n":"武侠仙侠","v":"205"},{"n":"历史军事","v":"56"},{"n":"科幻末世","v":"64"},{"n":"游戏竞技","v":"75"},{"n":"体育赛事","v":"206"},{"n":"奇闻异事","v":"204"}]}], + "2": [{key: "type", name: "类型", value: [{"n":"现代言情","v":"1"},{"n":"古代言情","v":"2"},{"n":"幻想言情","v":"4"},{"n":"宫闱宅斗","v":"209"}]}], + "3": [{key: "type", name: "类型", value: [{"n":"悬疑推理","v":"262"},{"n":"文学艺术","v":"240"},{"n":"历史传记","v":"264"}]}] + }, + filter_url: "{{fl.type}}", + filter_def: {}, + headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}, + sign_headers: { + "app-version": "51110", "platform": "android", "reg": "0", "AUTHORIZATION": "", + "application-id": "com.****.reader", "net-env": "1", "channel": "unknown", "qm-params": "" + }, + timeout: 10000, + play_parse: true, + + request: async function (url, obj) { + obj = obj || {}; + const response = await _fetch(url, { + method: obj.method || 'GET', + headers: obj.headers || this.headers + }); + return response.text(); + }, + + 预处理: async function () { + this.sign_headers.sign = getSignStr(this.sign_headers); + }, + + 一级: async function (tid, pg, filter, extend) { + let d = []; + const cateMap = {'1':'202', '2':'1', '3':'262'}; + let gender = tid !== '-1' ? tid : '2'; + let category_id = cateMap[gender]; + const validSubTypes = ['202','203','205','56','64','75','206','204','1','2','4','209','262','240','264']; + if (extend?.type && validSubTypes.includes(extend.type)) { + category_id = extend.type; + } else if (filter && validSubTypes.includes(filter)) { + category_id = filter; + } + let params = { + gender: gender, + category_id: category_id, + need_filters: '1', + page: pg || '1', + need_category: '1', + imei_ip: '2937357107' + }; + params.sign = getSignStr(params); + let html = await this.request(buildUrl(`${this.host}/api/v4/category/get-list`, params), {headers: this.sign_headers}); + let json = JSON.parse(html); + if (json?.data?.books) { + d = json.data.books.map(it => ({ + title: it.title, + url: `${this.host}/api/v4/book/detail?id=${it.id}`, + desc: it.author, + pic_url: it.image_link, + content: it.intro + })); + } + return setResult(d); + }, + + 二级: async function () { + let VOD = {}; + let bookId = this.input.match(/id=(\d+)/)[1]; + let detailParams = {id: bookId, imei_ip: '2937357107', teeny_mode: '0'}; + detailParams.sign = getSignStr(detailParams); + let detailHtml = await this.request(buildUrl(`${this.host}/api/v4/book/detail`, detailParams), {headers: this.sign_headers}); + let detailJson = JSON.parse(detailHtml); + if (detailJson?.data?.book) { + let book = detailJson.data.book; + VOD = { + vod_name: book.title, + type_name: book.book_tag_list?.map(tag => tag.title).join(',') || '', + vod_pic: book.image_link, + vod_content: book.intro, + vod_remarks: book.latest_chapter_title, + vod_year: '', vod_area: '', + vod_actor: book.author, vod_director: book.author, + vod_play_from: '阅读助手' + }; + let tocParams = {id: book.id}; + tocParams.sign = getSignStr(tocParams); + let tocHtml = await this.request(buildUrl('https://api-ks.wtzw.com/api/v1/chapter/chapter-list', tocParams), {headers: this.sign_headers}); + let tocJson = JSON.parse(tocHtml); + if (tocJson?.data?.chapter_lists) { + VOD.vod_play_url = tocJson.data.chapter_lists.map(chapter => + `${chapter.title}$${book.id}@@${chapter.id}@@${chapter.title}` + ).join('#'); + } + } + return VOD; + }, + + 搜索: async function () { + let d = []; + let params = { + gender: '3', imei_ip: '2937357107', + page: this.MY_PAGE, wd: this.KEY + }; + params.sign = getSignStr(params); + let html = await this.request(buildUrl(`${this.host}/api/v5/search/words`, params), {headers: this.sign_headers}); + let json = JSON.parse(html); + if (json?.data?.books) { + d = json.data.books.map(it => ({ + title: it.original_title, + desc: it.author, + pic_url: it.image_link, + url: `${this.host}/api/v4/book/detail?id=${it.id}`, + content: it.intro + })); + } + return setResult(d); + }, + + lazy: async function () { + let [bookId, chapterId, title] = this.input.split('@@'); + let content = '内容加载失败'; + let params = {id: bookId, chapterId}; + params.sign = getSignStr(params); + let html = await this.request(buildUrl('https://api-ks.wtzw.com/api/v1/chapter/content', params), {headers: this.sign_headers}); + let json = JSON.parse(html); + if (json?.data?.content) content = decodeContent(json.data.content); + return { + parse: 0, + url: `novel://${JSON.stringify({title, content})}`, + js: '' + }; + } +}; + +function getSignStr(params) { + const sign_key = "d3dGiJc651gSQ8w1"; + return md5(Object.keys(params).sort().reduce((pre, n) => pre + n + "=" + params[n], "") + sign_key); +} + +function decodeContent(content) { + let key = CryptoJS.enc.Utf8.parse("242ccb8230d709e1"); + let ivEncData = CryptoJS.enc.Base64.parse(content); + let iv = CryptoJS.lib.WordArray.create(ivEncData.words.slice(0, 4)); + let encrypted = CryptoJS.lib.WordArray.create(ivEncData.words.slice(4)); + let decrypted = CryptoJS.AES.decrypt({ciphertext: encrypted}, key, { + iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 + }); + return decrypted.toString(CryptoJS.enc.Utf8); +} \ No newline at end of file From 08b37be00cc6b53184608ac1ade6b33cdabcb0fe Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 00:12:49 +0800 Subject: [PATCH 23/99] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=89=E4=B8=AA?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\212\250\346\274\253[\346\274\253].js" | 105 ----- ...\346\274\253\345\246\226[\346\274\253].js" | 89 ---- ...51\347\251\272\345\275\261\350\247\206.py" | 428 ------------------ 3 files changed, 622 deletions(-) delete mode 100644 "spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" delete mode 100644 "spider/js/\345\212\250\346\274\253\345\246\226[\346\274\253].js" delete mode 100644 "spider/py/\345\244\251\347\251\272\345\275\261\350\247\206.py" diff --git "a/spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" "b/spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" deleted file mode 100644 index 0d1fa82a..00000000 --- "a/spider/catvod/\351\243\216\350\275\246\345\212\250\346\274\253[\346\274\253].js" +++ /dev/null @@ -1,105 +0,0 @@ -/* -@header({ - searchable: 1, - filterable: 1, - quickSearch: 1, - title: '风车动漫', - lang: 'cat' -}) -*/ -import {urljoin, parseList, parseDetail, lazy, request, cheerio, CryptoJS} from "./_dsutil.js"; - -const host = 'https://www.dmla5.com'; - -function init(cfg) { - const ext = cfg.ext; -} - -async function home(filter) { - let html = await request(host); - const $ = cheerio.load(html); - const listItems = $('.stui-header__menu li:gt(0):lt(4)'); - let classes = []; - listItems.each((index, element) => { - const item = $(element); - // 提取数据 - const type_name = item.find('a').text().trim(); - const type_id = urljoin(host, item.find('a').attr('href')).match(/.*\/(.*?)\.html/)[1]; - - classes.push({ - type_name, - type_id, - }); - }); - let res = { - 'class': classes - }; - return JSON.stringify(res); -} - -async function homeVod(params) { - let html = await request(host); - const $ = cheerio.load(html); - const listItems = $('ul.stui-vodlist.clearfix li'); - const d = parseList($, host, listItems); - - return JSON.stringify({ - list: d - }); -} - -async function category(tid, pg, filter, extend) { - let url = `${host}/type/${tid}-${pg}.html`; - let html = await request(url); - const $ = cheerio.load(html); - const listItems = $('.stui-vodlist li'); - const d = parseList($, host, listItems); - - return JSON.stringify({ - list: d - }); -} - -async function detail(id) { - let url = urljoin(host, id); - let html = await request(url); - const $ = cheerio.load(html); - - const vod = parseDetail($, host, url); - return JSON.stringify({ - list: [vod] - }) -} - -async function play(flag, id, flags) { - console.log("play"); - return await lazy(urljoin(host, id)); -} - -async function search(wd, quick, pg) { - let url = `${host}/search/${wd}----------${pg}---.html`; - let html = await request(url); - const $ = cheerio.load(html); - const listItems = $('ul.stui-vodlist__media li'); - const d = parseList($, host, listItems); - - return JSON.stringify({ - list: d - }); -} - -function proxy(params) { - return [200, 'text/plain;charset=utf-8', 'ok', null]; -} - -// 导出函数对象 -export default { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - proxy: proxy, -} \ No newline at end of file diff --git "a/spider/js/\345\212\250\346\274\253\345\246\226[\346\274\253].js" "b/spider/js/\345\212\250\346\274\253\345\246\226[\346\274\253].js" deleted file mode 100644 index 230e9798..00000000 --- "a/spider/js/\345\212\250\346\274\253\345\246\226[\346\274\253].js" +++ /dev/null @@ -1,89 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 1, - quickSearch: 1, - title: '动漫豆', - author: '', - '类型': '动漫', - lang: 'ds' -}) -*/ - -var rule = { - author: '', - title: '动漫豆', - 类型: '动漫', - host: 'https://www.dmyao.com/', - searchable: 2, - quickSearch: 1, - filterable: 1, - headers: { - 'User-Agent': 'MOBILE_UA' - }, - url: '/s/fyfilter.html', - filter_url: '{{fl.cateId or "fyclass"}}-{{fl.area}}-{{fl.by}}-{{fl.class}}-{{fl.lang}}-{{fl.letter}}---fypage---{{fl.year}}', - detailUrl: '/show/fyid.html', - searchUrl: '/search/**----------fypage---.html', - class_name: '国产动漫&日韩动漫&欧美动漫&港台动漫&动漫电影', - class_url: 'cnanime&jpanime&ouanime&hkanime&animevod', - play_parse: true, - 推荐: '*', - 一级: '.module-items.module-poster-items-base a;a&&title;.lazyload&&data-original;.module-item-note&&Text;a&&href', - 二级: { - "title": "h1&&Text", - "img": ".module-info-pic&&img&&src", - "desc": ".module-info-item:contains(备注)&&Text;.module-info-tag-link:contains(动画)&&Text;.module-info-tag-link:contains(大陆)&&Text;.module-info-item:contains(主演) .module-info-item-content&&Text;.module-info-item:contains(导演) .module-info-item-content&&Text", - "content": ".module-info-introduction-content&&Text", - "tabs": ".module-tab-items-box&&span", - "lists": ".module-play-list-base:eq(#id) a" - }, - - 搜索: '.module-card-item.module-item;a&&title;.lazyload&&data-original;.module-item-note&&Text;a&&href', - - lazy: async function lazyFunc() { - let html = await request(input); - let kcode = JSON.parse(html.split('aaaa=')[1].split('<')[0]); - let kurl = kcode.url; - - if (/\.(m3u8|mp4)/.test(kurl)) { - input = { - jx: 0, - parse: 0, - url: kurl, - header: { - 'User-Agent': MOBILE_UA, - 'Referer': getHome(kurl) - } - }; - } else { - input = { - jx: 0, - parse: 1, - url: input - }; - } - }, - - filter_def: { - cnanime: { - cateId: 'cnanime' - }, - jpanime: { - cateId: 'jpanime' - }, - ouanime: { - cateId: 'ouanime' - }, - hkanime: { - cateId: 'hkanime' - }, - animevod: { - cateId: 'animevod' - },hongkong: { - cateId: 'hongkong' - } - }, - - filter: {"cnanime":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"搞笑","v":"搞笑"},{"n":"运动","v":"运动"},{"n":"励志","v":"励志"},{"n":"热血","v":"热血"},{"n":"战斗","v":"战斗"},{"n":"竞技","v":"竞技"},{"n":"校园","v":"校园"},{"n":"青春","v":"青春"},{"n":"爱情","v":"爱情"},{"n":"冒险","v":"冒险"},{"n":"后宫","v":"后宫"},{"n":"百合","v":"百合"},{"n":"治愈","v":"治愈"},{"n":"萝莉","v":"萝莉"},{"n":"魔法","v":"魔法"},{"n":"悬疑","v":"悬疑"},{"n":"推理","v":"推理"},{"n":"奇幻","v":"奇幻"},{"n":"神魔","v":"神魔"},{"n":"恐怖","v":"恐怖"},{"n":"血腥","v":"血腥"},{"n":"机战","v":"机战"},{"n":"战争","v":"战争"},{"n":"犯罪","v":"犯罪"},{"n":"剧情","v":"剧情"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2025","v":"2025"},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"},{"n":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"},{"n":"1999","v":"1999"},{"n":"1998","v":"1998"},{"n":"1997","v":"1997"},{"n":"1996","v":"1996"},{"n":"1995","v":"1995"},{"n":"1994","v":"1994"},{"n":"1993","v":"1993"},{"n":"1992","v":"1992"},{"n":"1991","v":"1991"},{"n":"1990","v":"1990"},{"n":"1989","v":"1989"},{"n":"1988","v":"1988"},{"n":"1987","v":"1987"},{"n":"1986","v":"1986"},{"n":"1985","v":"1985"},{"n":"1984","v":"1984"},{"n":"1980","v":"1980"},{"n":"1970","v":"1970"}]},{"key":"by","name":"排序","value":[{"n":"时间排序","v":"time"},{"n":"人气排序","v":"hits"},{"n":"评分排序","v":"score"}]}],"jpanime":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"搞笑","v":"搞笑"},{"n":"运动","v":"运动"},{"n":"励志","v":"励志"},{"n":"热血","v":"热血"},{"n":"战斗","v":"战斗"},{"n":"竞技","v":"竞技"},{"n":"校园","v":"校园"},{"n":"青春","v":"青春"},{"n":"爱情","v":"爱情"},{"n":"冒险","v":"冒险"},{"n":"后宫","v":"后宫"},{"n":"百合","v":"百合"},{"n":"治愈","v":"治愈"},{"n":"萝莉","v":"萝莉"},{"n":"魔法","v":"魔法"},{"n":"悬疑","v":"悬疑"},{"n":"推理","v":"推理"},{"n":"奇幻","v":"奇幻"},{"n":"神魔","v":"神魔"},{"n":"恐怖","v":"恐怖"},{"n":"血腥","v":"血腥"},{"n":"机战","v":"机战"},{"n":"战争","v":"战争"},{"n":"犯罪","v":"犯罪"},{"n":"剧情","v":"剧情"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2025","v":"2025"},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"},{"n":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"},{"n":"1999","v":"1999"},{"n":"1998","v":"1998"},{"n":"1997","v":"1997"},{"n":"1996","v":"1996"},{"n":"1995","v":"1995"},{"n":"1994","v":"1994"},{"n":"1993","v":"1993"},{"n":"1992","v":"1992"},{"n":"1991","v":"1991"},{"n":"1990","v":"1990"},{"n":"1989","v":"1989"},{"n":"1988","v":"1988"},{"n":"1987","v":"1987"},{"n":"1986","v":"1986"},{"n":"1985","v":"1985"},{"n":"1984","v":"1984"},{"n":"1980","v":"1980"},{"n":"1970","v":"1970"}]},{"key":"by","name":"排序","value":[{"n":"时间排序","v":"time"},{"n":"人气排序","v":"hits"},{"n":"评分排序","v":"score"}]}],"ouanime":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"搞笑","v":"搞笑"},{"n":"运动","v":"运动"},{"n":"励志","v":"励志"},{"n":"热血","v":"热血"},{"n":"战斗","v":"战斗"},{"n":"竞技","v":"竞技"},{"n":"校园","v":"校园"},{"n":"青春","v":"青春"},{"n":"爱情","v":"爱情"},{"n":"冒险","v":"冒险"},{"n":"后宫","v":"后宫"},{"n":"百合","v":"百合"},{"n":"治愈","v":"治愈"},{"n":"萝莉","v":"萝莉"},{"n":"魔法","v":"魔法"},{"n":"悬疑","v":"悬疑"},{"n":"推理","v":"推理"},{"n":"奇幻","v":"奇幻"},{"n":"神魔","v":"神魔"},{"n":"恐怖","v":"恐怖"},{"n":"血腥","v":"血腥"},{"n":"机战","v":"机战"},{"n":"战争","v":"战争"},{"n":"犯罪","v":"犯罪"},{"n":"剧情","v":"剧情"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2025","v":"2025"},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"},{"n":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"},{"n":"1999","v":"1999"},{"n":"1998","v":"1998"},{"n":"1997","v":"1997"},{"n":"1996","v":"1996"},{"n":"1995","v":"1995"},{"n":"1994","v":"1994"},{"n":"1993","v":"1993"},{"n":"1992","v":"1992"},{"n":"1991","v":"1991"},{"n":"1990","v":"1990"},{"n":"1989","v":"1989"},{"n":"1988","v":"1988"},{"n":"1987","v":"1987"},{"n":"1986","v":"1986"},{"n":"1985","v":"1985"},{"n":"1984","v":"1984"},{"n":"1980","v":"1980"},{"n":"1970","v":"1970"}]},{"key":"by","name":"排序","value":[{"n":"时间排序","v":"time"},{"n":"人气排序","v":"hits"},{"n":"评分排序","v":"score"}]}],"hkanime":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"搞笑","v":"搞笑"},{"n":"运动","v":"运动"},{"n":"励志","v":"励志"},{"n":"热血","v":"热血"},{"n":"战斗","v":"战斗"},{"n":"竞技","v":"竞技"},{"n":"校园","v":"校园"},{"n":"青春","v":"青春"},{"n":"爱情","v":"爱情"},{"n":"冒险","v":"冒险"},{"n":"后宫","v":"后宫"},{"n":"百合","v":"百合"},{"n":"治愈","v":"治愈"},{"n":"萝莉","v":"萝莉"},{"n":"魔法","v":"魔法"},{"n":"悬疑","v":"悬疑"},{"n":"推理","v":"推理"},{"n":"奇幻","v":"奇幻"},{"n":"神魔","v":"神魔"},{"n":"恐怖","v":"恐怖"},{"n":"血腥","v":"血腥"},{"n":"机战","v":"机战"},{"n":"战争","v":"战争"},{"n":"犯罪","v":"犯罪"},{"n":"剧情","v":"剧情"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2025","v":"2025"},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"},{"n":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"},{"n":"1999","v":"1999"},{"n":"1998","v":"1998"},{"n":"1997","v":"1997"},{"n":"1996","v":"1996"},{"n":"1995","v":"1995"},{"n":"1994","v":"1994"},{"n":"1993","v":"1993"},{"n":"1992","v":"1992"},{"n":"1991","v":"1991"},{"n":"1990","v":"1990"},{"n":"1989","v":"1989"},{"n":"1988","v":"1988"},{"n":"1987","v":"1987"},{"n":"1986","v":"1986"},{"n":"1985","v":"1985"},{"n":"1984","v":"1984"},{"n":"1980","v":"1980"},{"n":"1970","v":"1970"}]},{"key":"by","name":"排序","value":[{"n":"时间排序","v":"time"},{"n":"人气排序","v":"hits"},{"n":"评分排序","v":"score"}]}],"animevod":[{"key":"class","name":"剧情","value":[{"n":"全部","v":""},{"n":"搞笑","v":"搞笑"},{"n":"运动","v":"运动"},{"n":"励志","v":"励志"},{"n":"热血","v":"热血"},{"n":"战斗","v":"战斗"},{"n":"竞技","v":"竞技"},{"n":"校园","v":"校园"},{"n":"青春","v":"青春"},{"n":"爱情","v":"爱情"},{"n":"冒险","v":"冒险"},{"n":"后宫","v":"后宫"},{"n":"百合","v":"百合"},{"n":"治愈","v":"治愈"},{"n":"萝莉","v":"萝莉"},{"n":"魔法","v":"魔法"},{"n":"悬疑","v":"悬疑"},{"n":"推理","v":"推理"},{"n":"奇幻","v":"奇幻"},{"n":"神魔","v":"神魔"},{"n":"恐怖","v":"恐怖"},{"n":"血腥","v":"血腥"},{"n":"机战","v":"机战"},{"n":"战争","v":"战争"},{"n":"犯罪","v":"犯罪"},{"n":"剧情","v":"剧情"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2025","v":"2025"},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"},{"n":"2007","v":"2007"},{"n":"2006","v":"2006"},{"n":"2005","v":"2005"},{"n":"2004","v":"2004"},{"n":"2003","v":"2003"},{"n":"2002","v":"2002"},{"n":"2001","v":"2001"},{"n":"2000","v":"2000"},{"n":"1999","v":"1999"},{"n":"1998","v":"1998"},{"n":"1997","v":"1997"},{"n":"1996","v":"1996"},{"n":"1995","v":"1995"},{"n":"1994","v":"1994"},{"n":"1993","v":"1993"},{"n":"1992","v":"1992"},{"n":"1991","v":"1991"},{"n":"1990","v":"1990"},{"n":"1989","v":"1989"},{"n":"1988","v":"1988"},{"n":"1987","v":"1987"},{"n":"1986","v":"1986"},{"n":"1985","v":"1985"},{"n":"1984","v":"1984"},{"n":"1980","v":"1980"},{"n":"1970","v":"1970"}]},{"key":"by","name":"排序","value":[{"n":"时间排序","v":"time"},{"n":"人气排序","v":"hits"},{"n":"评分排序","v":"score"}]}]} -} \ No newline at end of file diff --git "a/spider/py/\345\244\251\347\251\272\345\275\261\350\247\206.py" "b/spider/py/\345\244\251\347\251\272\345\275\261\350\247\206.py" deleted file mode 100644 index b8ac80bf..00000000 --- "a/spider/py/\345\244\251\347\251\272\345\275\261\350\247\206.py" +++ /dev/null @@ -1,428 +0,0 @@ -""" -@header({ - searchable: 1, - filterable: 1, - quickSearch: 1, - title: '天空影视', - lang: 'hipy' -}) -""" - -from Crypto.PublicKey import RSA -from Crypto.Util.Padding import pad -from Crypto.Cipher import AES, PKCS1_v1_5 -import sys,time,json,base64,urllib3,hashlib -urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -sys.path.append('..') -try: - # from base.spider import Spider as BaseSpider - from base.spider import BaseSpider -except ImportError: - from t4.base.spider import BaseSpider - -class Spider(BaseSpider): - host, android_id, init_sign_salt, app_cert_sha1, private_key, token, timeout, headers = ('','','','','','','', - { - 'User-Agent': "okhttp-okgo/jeasonlzy", - 'Connection': "Keep-Alive", - 'Accept-Encoding': "gzip", - 'Accept-Language': "zh-CN,zh;q=0.8", - 'sign': "", - 'devicename': "Xiaomi 15", - 'deviceos': "15", - 'bundleid': "", - 'versionname': "2.1.0", - 'versioncode': "2001000", - 'vendor': "Xiaomi", - 'chid': "26002", - 'subchid': "26002", - 'os': "1", - 'screenpx': "2670*1200", - 'nettype': "wifi", - 'audit': "1", - 'force': "1" - }) - - def init(self, extend=''): - try: - config = json.loads(extend) - except (json.JSONDecodeError, TypeError): - config = {} - self.timeout = config.get('timeout', 15) - self.host = config.get('host', 'http://api-live.vfilm.life') - self.android_id = config.get('android_id', '6617a62678360a86') - self.init_sign_salt = config.get('init_sign_salt', 'lsdfnrtpmslscndy') - self.app_cert_sha1 = config.get('app_cert_sha1', '70:27:C9:DC:98:96:75:CD:35:DB:0C:CE:AC:CA:84:0A:B7:1E:B5:7F') - self.private_key = config.get('private_key', 'MIICWwIBAAKBgQDYJzTUOgYdR/eIhsjpNMYWQGYl3pBycwKDoL6KThpPwrZQ9+xv\nLSaPj92HQknVaWR/RD6tHVRysChoeqAFyyQUe4UXAYnJDNlurpELb5HUIBFgmO97\niIOJCK6zbmnHT6WOHYaODTqrmX6NBgLjoFiDYBPYxG1T/K1uZ47xQDHFQQIDAQAB\nAoGAEpT8Q6phUC8ZppD/wJya0tribSr++/fLJYmyF62zMVwp1DgcCUq2X+0cPD6E\nnmYbD53MTZGR6vId5y1ziEv4Y+nu5EUyDk1xeGIxojpLhxuRoCbBt+LMJ1YUxv6p\n6F4SNwQ10U78m829Ud50mJBvkt2Vg8607SUrWheydvWHyAECQQDvayhgX5XEFaha\nUtPp5pPIkKBqHnLGm4et8be/jIIFhY9CIJbKLsqc0OFwNvz46GtRQwrtHP7LxTEF\nYT0C6CahAkEA5x+OqN/iykZIHc6Z2qZfAiLjPnQJu9DTXC/kt3TlsCc3XPNkXlAu\nq786LluH6dzQfDbLpmODtzNWavfgCtE6oQJAdTsJKDdlg//+0UthTFSE5F48zfle\nxfT9+KQ1Duvj9oQxY3XFn/ZNa3+0A1hJgi977Oxg+z2JXYmOuU2lrDi0QQJAMWwA\nF4B4gIRy21zYbXbyDgTjzvEFO9I1wBrFr60hiH96STgKmFhRAozLpioQcCO1uToG\nZjgVbFFgA1Op5uZCwQJAL1ziHIphaoCpHnnESidt3Nlrzqj/5uEpdHu7ZvPuZYya\nU8e1AhjeP+zKvfJUiXwDGuDZLx5Xe0BK8Bu72sdKcQ==') - self.headers['bundleid'] = config.get('bundleid', 'com.ytwl.fhtq') - self.token = config.get('token', '') - imsi_id = config.get('imsi_id', '1') - self.headers['sign'] = self.sign_encrypt(f'jing##&&&wei##&&&fuwu##{imsi_id}&&&idian##&&&she##{self.android_id}&&&mdian##{self.android_id}&&&olian##&&&an##{self.android_id}') - - def homeContent(self, filter): - if not self.host: return None - timestamp = self.timestamp() - payload = { - 'applock': "0", - 'ncode': self.init_sign(timestamp), - 'force': "1", - 'retime': timestamp - } - response = self.post(f'{self.host}/news/tv/columns', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - classes = [] - for i in response['data']['list']: - if i['is_show_recommend'] == 1: - home_class_id = i.get('column_id') - continue - classes.append({'type_id': i['column_id'], 'type_name': i['name']}) - timestamp = self.timestamp() - payload = { - 'column_id': home_class_id or '164', - 'ncode': self.init_sign(timestamp), - 'page': "1", - 'retime': timestamp - } - response = self.post(f'{self.host}/news/tv/sectionsPageByColumn', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - section_list = response['data']['section_list'] - videos = [] - for i in section_list: - for j in i.get('tv_list', []): - videos.append({ - 'vod_id': j.get('news_id'), - 'vod_name': j.get('title', j.get('sub_title')), - 'vod_pic': j.get('ver_pic') - }) - return {'class': classes, 'list': videos} - - def categoryContent(self, tid, pg, filter, extend): - timestamp = self.timestamp() - payload = { - 'column_id': tid, - 'ncode': self.init_sign(timestamp), - 'page': pg, - 'retime': timestamp - } - response = self.post(f'{self.host}/news/tv/tvListByColumn', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - videos = [] - for i in response['data']['list']: - up_count = i.get('up_count', '') - if up_count: - up_count = f'{up_count}集' - videos.append({ - 'vod_id': i.get('news_id'), - 'vod_name': i.get('title'), - 'vod_pic': i.get('ver_pic'), - 'vod_remarks': up_count, - 'vod_area': i.get('area'), - 'vod_class': i.get('cat'), - 'vod_score': i.get('score'), - 'vod_year': i.get('pubdate') - }) - return {'list': videos, 'page': pg} - - def searchContent(self, key, quick, pg='1'): - timestamp = self.timestamp() - payload = { - 'ncode': self.init_sign(timestamp), - 'signKey': self.signKey(timestamp), - 'page': pg, - 'is_check': "0", - 'keyword': key, - 'retime': timestamp - } - response = self.post(f'{self.host}/search/wordinfo', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - videos = [] - for i in response['data']['search_list']: - for j in i.get('list',[]): - vod_remarks = j.get('up_count') - if vod_remarks: - vod_remarks = f'{vod_remarks}集' - else: - vod_remarks = j.get('news_type_name') - videos.append({ - 'vod_id': j.get('news_id'), - 'vod_name': j.get('origin_title',j.get('title')), - 'vod_pic': j.get('ver_pic'), - 'vod_content': j.get('desc'), - 'vod_remarks': vod_remarks, - 'vod_area': j.get('area'), - }) - return {'list': videos, 'page': pg} - - def detailContent(self, ids): - timestamp = self.timestamp() - payload = { - 'ncode': self.init_sign(timestamp), - 'signKey': self.signKey(timestamp), - 'news_id': ids[0], - 'retime': timestamp - } - response = self.post(f'{self.host}/news/tv/detail', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - data = response['data'] - timestamp2 = self.timestamp() - payload = { - 'next': "0", - 'pl_id': "", - 'playlink_num': "1", - 'ncode': self.init_sign(timestamp2), - 'format': "high", - 'mobile': "", - 'check': "0", - 'mpl_id': "", - 'news_id': ids[0], - 'retime': timestamp2, - 'resite': "", - 'signKey': self.signKey(timestamp2), - 'bid': "300", - 'retry': "0" - } - response = self.post(f'{self.host}/news/tv/multiDetail', data=payload, headers=self.headers, timeout=self.timeout, verify=False).json() - data_ = response['data']['data'] - data2_ = self.decrypt(data_) - data2 = json.loads(data2_) - max_up_count = data2.get('max_up_count',data2.get('up_count')) - news_id = data2['news_id'] - site_list_test = data2.get('test') - if site_list_test: - site_list = site_list_test.get('site_list',[]) - vod_play_froms = [] - vod_play_froms.extend(site_list) - vod_play_froms = [str(item) for item in vod_play_froms] - vod_play_urls = [] - for i in vod_play_froms: - urls = [] - for j in range(1,int(max_up_count) + 1): - urls.append(f"第{j}集${j}@{news_id}@{i}") - vod_play_urls.append('#'.join(urls)) - videos = [] - up_count = data.get('up_count',data.get('max_up_count')) - if up_count: - up_count = f'{up_count}集' - videos.append({ - 'vod_id': data.get('news_id'), - 'vod_name': data.get('title'), - 'vod_content': data.get('desc'), - 'vod_director': data.get('dir'), - 'vod_actor': data.get('act'), - 'vod_class': data.get('cat'), - 'vod_remarks': up_count, - 'vod_area': data.get('area'), - 'vod_play_from': '$$$'.join(vod_play_froms), - 'vod_play_url': '$$$'.join(vod_play_urls) - }) - return {'list': videos} - - def playerContent(self, flag, id, vipflags): - jx, url, play_header = 0, '', {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 15; 24129PN74C Build/AP3A.240617.008)'} - episodes, news_id, resite = id.split('@', 2) - timestamp = self.timestamp() - payload = { - 'next': "0", - 'pl_id': "", - 'playlink_num': episodes, - 'ncode': self.init_sign(timestamp), - 'format': 'high', - 'mobile': "", - 'check': "0", - 'mpl_id': "", - 'news_id': news_id, - 'retime': timestamp, - 'resite': resite, - 'signKey': self.signKey(timestamp), - 'bid': '300', - 'retry': "0" - } - response = self.post(f'{self.host}/news/tv/multiDetail', data=payload, headers=self.headers,timeout=self.timeout, verify=False).json() - data_ = response['data']['data'] - data_ = self.decrypt(data_) - data = json.loads(data_) - url_list = data.get('url_list', []) - if url_list: - for i in url_list: - play_url = i.get('surl', '') - if play_url.startswith('http'): - url = play_url - break - if url: - return {'jx': 0, 'parse': 0, 'url': url, 'header': play_header} - cp_data = data['cp_data'] - wanneng = cp_data.get('wanneng', '') - parse_url = '' - if wanneng and isinstance(wanneng, dict): - parse_url = wanneng.get('postUrl', '') - type = cp_data.get('TYPE') - if type == 'DIRECT': - for i in cp_data['V']: - for j in i.values(): - if j.startswith(('http://', 'https://')): - play_url = j - break - if 'play_url' in locals() and play_url: - return {'jx': jx, 'parse': 0, 'url': play_url, 'header': play_header} - try: - if parse_url: - parse_data = self.fetch(parse_url, headers={'User-Agent': "okhttp/3.10.0", 'Accept-Encoding': "gzip"}, timeout=self.timeout, verify=False).text - except Exception: - return {'jx': 0, 'parse': 0, 'url': ''} - if not parse_data: - return {'jx': 0, 'parse': 0, 'url': ''} - timestamp2 = self.timestamp() - vid_format = data.get('format', 'high') - payload2 = { - 'pl_id': data.get('pl_id', ''), - 'is_down': data.get('is_down', '0'), - 'data': parse_data, - 'playlink_num': episodes, - 'ncode': self.init_sign(timestamp), - 'format': vid_format, - 'cp_id': data.get('cp_id', ''), - 'mpl_id': data.get('mpl_id', ''), - 'url': data['web_url'], - 'retime': timestamp2, - 'wn_info': json.dumps(data['cp_data'].get('wanneng', '')), - 'site': data['site'], - 'news_type': "null", - 'web_url': data['web_url'], - 'mc': "null", - 'bid': self.bid(vid_format) - } - response = self.post(f'{self.host}/parse/index/parse', data=payload2, headers=self.headers, timeout=self.timeout, verify=False).json() - data2_ = response['data']['data'] - data2_ = self.decrypt(data2_) - data2 = json.loads(data2_) - play_url = data2['video'][0]['url'] - if play_url.startswith('http'): - url = play_url - return {'jx': jx, 'parse': 0, 'url': url, 'header': play_header} - - def timestamp(self): - timestamp = time.time() - return str(int(round(timestamp * 1000))) - - def md5(self,str): - md5_hash = hashlib.md5() - md5_hash.update(str.encode('utf-8')) - return md5_hash.hexdigest() - - def init_sign(self, timestamp): - first_md5 = self.md5(f"{self.init_sign_salt}{self.token}{self.android_id}{timestamp}") - combined = first_md5[:10] + first_md5[22:] - return self.md5(combined) - - def get_strings(self, str_param, str2_param): - strlist = [ - "afv", "Cs", "D", "bd", "cs", "h", "i0", "j0", "K", "L", "M8", "N", "O", "P", "Q", "R", - "k", "l", "m", "n", "o", "p", "q", "r", "s", "t7", "Z", "A", "B", "E", "F", "G", "H", "I", - "J", "S16", "T", "d", "e", "f", "g", "U", "V", "W6", "u", "v", "w", "x", "y", "Xd", "Y", - "Za0", "gw", "Us", "Vd", "Wv", "X", "Y", "Zx4", "afv", "Cs", "D", "bd", "cs", "h", "i", - "j", "K0", "L", "M", "N", "O0", "P", "Q", "R", "k", "l1", "m", "n", "o", "p", "q", "r", - "s1", "t", "Z", "A", "B", "E", "F5", "G", "H", "I0", "J", "S", "T", "d", "e", "f", "g1", - "U1", "V", "W3", "u", "v2", "w", "x", "y", "Xd", "Y", "Za", "gw", "Us", "Vd", "Wv", "X", - "Y", "Zx" - ] - bytes_data = str_param.encode('utf-8') - as_list = strlist.copy() - if str2_param and len(str2_param) > 0: - for s in str2_param.split(','): - as_list.append(s) - sb = [] - for i in range(len(bytes_data)): - abs_val = abs(bytes_data[i] - i) % 100 - if abs_val < len(as_list): - sb.append(as_list[abs_val]) - return ''.join(sb) + "==" - - def send_increment_data(self, str_param, str2_param, str3_param=None): - bytes_data = str2_param.encode('utf-8') - sb = [] - loop_count = len(bytes_data) // 2 - for i in range(loop_count): - index = (len(bytes_data) - (i % 8)) - 1 - b = bytes_data[index] - sb.append(str(abs(bytes_data[i] - b) % 100)) - sb.append("$") - sb.append(str((bytes_data[(len(bytes_data) - 1) - i] + b) % 100)) - sb.append("$") - substring = ''.join(sb)[loop_count:] - strings = self.get_strings(substring, str3_param) - result = str_param + strings - return result - - def sign_encrypt(self,text): - key = "ZXJsaW5nZXJlcm5pYW5zaXl1ZWVyc2hp".encode('utf-8') - cipher = AES.new(key, AES.MODE_ECB) - text_bytes = text.encode('utf-8') - padded_text = pad(text_bytes, AES.block_size) - encrypted_bytes = cipher.encrypt(padded_text) - encrypted_base64 = base64.b64encode(encrypted_bytes).decode('utf-8') - return encrypted_base64 - - def decrypt(self, encrypted_data): - try: - private_key = self.private_key - if not private_key.startswith('-----'): - private_key = f'-----BEGIN RSA PRIVATE KEY-----\n{private_key}\n-----END RSA PRIVATE KEY-----' - private_key = RSA.importKey(private_key) - cipher = PKCS1_v1_5.new(private_key) - decoded_data = base64.b64decode(encrypted_data) - key_size = private_key.size_in_bytes() - decrypted_text_parts = [] - if len(decoded_data) > key_size: - i = 0 - while i < len(decoded_data): - chunk = decoded_data[i:i + key_size] - decrypted_chunk = cipher.decrypt(chunk, None) - if decrypted_chunk is None: - raise ValueError("解密失败,可能是数据损坏或密钥不匹配") - decrypted_text_parts.append(decrypted_chunk.decode('utf-8')) - i += key_size - else: - decrypted_data = cipher.decrypt(decoded_data, None) - if decrypted_data is None: - raise ValueError("解密失败,可能是数据损坏或密钥不匹配") - decrypted_text_parts.append(decrypted_data.decode('utf-8')) - return ''.join(decrypted_text_parts) - except Exception: - return None - - def signKey(self,timestamp): - return self.send_increment_data(timestamp, f'{self.android_id}{self.md5(self.app_cert_sha1)}{timestamp}') - - def bid(self, str_param): - str_to_c2 = { - "fluent": 2, "normal": 4, "super2": 15, "4K": 22, "4k": 23, "原画": 13, - "标清": 3, "极速": 1, "流畅": 0, "蓝光": 14, "超清": 9, "高清": 5, - "360P": 17, "360p": 16, "540P": 8, "540p": 7, "720P": 12, "720p": 11, - "high": 6, "1080P": 19, "1080p": 18, "1280P": 21, "1280p": 20, "super": 10 - } - result_mapping = [ - (0, 2, "200", "fluent"), (3, 4, "300", "normal"), (5, 8, "300", "high"), (9, 10, "500", "super"), - (11, 12, "400", "super2"), - (13, 15, "600", "super2"), (16, 17, "200", "normal"), (18, 19, "500", "super2"), (20, 21, "600", "super2"), - (22, 23, "800", "super2") - ] - if not str_param: - return {} - c2 = str_to_c2.get(str_param, 65535) - for min_val, max_val, bid, fmt in result_mapping: - if min_val <= c2 <= max_val: - return bid - return "300" - - def homeVideoContent(self): - pass - - def getName(self): - pass - - def isVideoFormat(self, url): - pass - - def manualVideoCheck(self): - pass - - def destroy(self): - pass - - def localProxy(self, param): - pass \ No newline at end of file From 06e8d5ab483513df2533d9606cef0e9ac5431b7b Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 10:25:52 +0800 Subject: [PATCH 24/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A3=B0=E6=BC=AB?= =?UTF-8?q?=E7=94=B5=E5=8F=B0[=E4=B9=A6].js=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\212\251\346\211\213[\344\271\246].js" | 173 ++---------------- 1 file changed, 13 insertions(+), 160 deletions(-) diff --git "a/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" index 40f61d11..051389c6 100644 --- "a/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" +++ "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" @@ -1,160 +1,13 @@ -var rule = { - 类型: '小说', - author: 'EylinSir', - title: '阅读助手[书]', - desc: '阅读助手小说源', - host: 'https://api-bc.wtzw.com', - homeUrl: 'https://api-bc.wtzw.com', - url: '/api/v4/category/get-list?gender=fyclass&category_id=fyfilter&need_filters=1&page=fypage&need_category=1', - class_name: '男生&女生&出版', - class_url: '1&2&3', - searchUrl: '/api/v5/search/words?gender=3&imei_ip=2937357107&page=fypage&wd=**', - searchable: 2, - quickSearch: 0, - filterable: 1, - filter: { - "1": [{key: "type", name: "类型", value: [{"n":"玄幻奇幻","v":"202"},{"n":"都市人生","v":"203"},{"n":"武侠仙侠","v":"205"},{"n":"历史军事","v":"56"},{"n":"科幻末世","v":"64"},{"n":"游戏竞技","v":"75"},{"n":"体育赛事","v":"206"},{"n":"奇闻异事","v":"204"}]}], - "2": [{key: "type", name: "类型", value: [{"n":"现代言情","v":"1"},{"n":"古代言情","v":"2"},{"n":"幻想言情","v":"4"},{"n":"宫闱宅斗","v":"209"}]}], - "3": [{key: "type", name: "类型", value: [{"n":"悬疑推理","v":"262"},{"n":"文学艺术","v":"240"},{"n":"历史传记","v":"264"}]}] - }, - filter_url: "{{fl.type}}", - filter_def: {}, - headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'}, - sign_headers: { - "app-version": "51110", "platform": "android", "reg": "0", "AUTHORIZATION": "", - "application-id": "com.****.reader", "net-env": "1", "channel": "unknown", "qm-params": "" - }, - timeout: 10000, - play_parse: true, - - request: async function (url, obj) { - obj = obj || {}; - const response = await _fetch(url, { - method: obj.method || 'GET', - headers: obj.headers || this.headers - }); - return response.text(); - }, - - 预处理: async function () { - this.sign_headers.sign = getSignStr(this.sign_headers); - }, - - 一级: async function (tid, pg, filter, extend) { - let d = []; - const cateMap = {'1':'202', '2':'1', '3':'262'}; - let gender = tid !== '-1' ? tid : '2'; - let category_id = cateMap[gender]; - const validSubTypes = ['202','203','205','56','64','75','206','204','1','2','4','209','262','240','264']; - if (extend?.type && validSubTypes.includes(extend.type)) { - category_id = extend.type; - } else if (filter && validSubTypes.includes(filter)) { - category_id = filter; - } - let params = { - gender: gender, - category_id: category_id, - need_filters: '1', - page: pg || '1', - need_category: '1', - imei_ip: '2937357107' - }; - params.sign = getSignStr(params); - let html = await this.request(buildUrl(`${this.host}/api/v4/category/get-list`, params), {headers: this.sign_headers}); - let json = JSON.parse(html); - if (json?.data?.books) { - d = json.data.books.map(it => ({ - title: it.title, - url: `${this.host}/api/v4/book/detail?id=${it.id}`, - desc: it.author, - pic_url: it.image_link, - content: it.intro - })); - } - return setResult(d); - }, - - 二级: async function () { - let VOD = {}; - let bookId = this.input.match(/id=(\d+)/)[1]; - let detailParams = {id: bookId, imei_ip: '2937357107', teeny_mode: '0'}; - detailParams.sign = getSignStr(detailParams); - let detailHtml = await this.request(buildUrl(`${this.host}/api/v4/book/detail`, detailParams), {headers: this.sign_headers}); - let detailJson = JSON.parse(detailHtml); - if (detailJson?.data?.book) { - let book = detailJson.data.book; - VOD = { - vod_name: book.title, - type_name: book.book_tag_list?.map(tag => tag.title).join(',') || '', - vod_pic: book.image_link, - vod_content: book.intro, - vod_remarks: book.latest_chapter_title, - vod_year: '', vod_area: '', - vod_actor: book.author, vod_director: book.author, - vod_play_from: '阅读助手' - }; - let tocParams = {id: book.id}; - tocParams.sign = getSignStr(tocParams); - let tocHtml = await this.request(buildUrl('https://api-ks.wtzw.com/api/v1/chapter/chapter-list', tocParams), {headers: this.sign_headers}); - let tocJson = JSON.parse(tocHtml); - if (tocJson?.data?.chapter_lists) { - VOD.vod_play_url = tocJson.data.chapter_lists.map(chapter => - `${chapter.title}$${book.id}@@${chapter.id}@@${chapter.title}` - ).join('#'); - } - } - return VOD; - }, - - 搜索: async function () { - let d = []; - let params = { - gender: '3', imei_ip: '2937357107', - page: this.MY_PAGE, wd: this.KEY - }; - params.sign = getSignStr(params); - let html = await this.request(buildUrl(`${this.host}/api/v5/search/words`, params), {headers: this.sign_headers}); - let json = JSON.parse(html); - if (json?.data?.books) { - d = json.data.books.map(it => ({ - title: it.original_title, - desc: it.author, - pic_url: it.image_link, - url: `${this.host}/api/v4/book/detail?id=${it.id}`, - content: it.intro - })); - } - return setResult(d); - }, - - lazy: async function () { - let [bookId, chapterId, title] = this.input.split('@@'); - let content = '内容加载失败'; - let params = {id: bookId, chapterId}; - params.sign = getSignStr(params); - let html = await this.request(buildUrl('https://api-ks.wtzw.com/api/v1/chapter/content', params), {headers: this.sign_headers}); - let json = JSON.parse(html); - if (json?.data?.content) content = decodeContent(json.data.content); - return { - parse: 0, - url: `novel://${JSON.stringify({title, content})}`, - js: '' - }; - } -}; - -function getSignStr(params) { - const sign_key = "d3dGiJc651gSQ8w1"; - return md5(Object.keys(params).sort().reduce((pre, n) => pre + n + "=" + params[n], "") + sign_key); -} - -function decodeContent(content) { - let key = CryptoJS.enc.Utf8.parse("242ccb8230d709e1"); - let ivEncData = CryptoJS.enc.Base64.parse(content); - let iv = CryptoJS.lib.WordArray.create(ivEncData.words.slice(0, 4)); - let encrypted = CryptoJS.lib.WordArray.create(ivEncData.words.slice(4)); - let decrypted = CryptoJS.AES.decrypt({ciphertext: encrypted}, key, { - iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 - }); - return decrypted.toString(CryptoJS.enc.Utf8); -} \ No newline at end of file +/* +@header({ + searchable: 2, + filterable: 1, + quickSearch: 0, + title: '阅读助手[书]', + author: 'EylinSir', + '类型': '小说', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflsI/or7QnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfpmIXor7vliqnmiYtb5LmmXScsCiAgICBkZXNjOiAn6ZiF6K+75Yqp5omL5bCP6K+05rqQJywKICAgIGhvc3Q6ICdodHRwczovL2FwaS1iYy53dHp3LmNvbScsCiAgICBjaGFwdGVySG9zdDogJ2h0dHBzOi8vYXBpLWtzLnd0encuY29tJywKICAgIGhvbWVVcmw6ICdodHRwczovL2FwaS1iYy53dHp3LmNvbScsCiAgICB1cmw6ICcvYXBpL3Y0L2NhdGVnb3J5L2dldC1saXN0P2dlbmRlcj1meWNsYXNzJmNhdGVnb3J5X2lkPWZ5ZmlsdGVyJm5lZWRfZmlsdGVycz0xJnBhZ2U9ZnlwYWdlJm5lZWRfY2F0ZWdvcnk9MScsCiAgICBjbGFzc19uYW1lOiAn55S355SfJuWls+eUnyblh7rniYgnLAogICAgY2xhc3NfdXJsOiAnMSYyJjMnLAogICAgc2VhcmNoVXJsOiAnL2FwaS92NS9zZWFyY2gvd29yZHM/Z2VuZGVyPTMmaW1laV9pcD0yOTM3MzU3MTA3JnBhZ2U9ZnlwYWdlJndkPSoqJywKICAgIHNlYXJjaGFibGU6IDIsCiAgICBxdWlja1NlYXJjaDogMCwKICAgIGZpbHRlcmFibGU6IDEsCiAgICBmaWx0ZXI6IHsKICAgICAgICAiMSI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IueOhOW5u+Wlh+W5uyIsInYiOiIyMDIifSx7Im4iOiLpg73luILkurrnlJ8iLCJ2IjoiMjAzIn0seyJuIjoi5q2m5L6g5LuZ5L6gIiwidiI6IjIwNSJ9LHsibiI6IuWOhuWPsuWGm+S6iyIsInYiOiI1NiJ9LHsibiI6IuenkeW5u+acq+S4liIsInYiOiI2NCJ9LHsibiI6Iua4uOaIj+ernuaKgCIsInYiOiI3NSJ9LHsibiI6IuS9k+iCsui1m+S6iyIsInYiOiIyMDYifSx7Im4iOiLlpYfpl7vlvILkuosiLCJ2IjoiMjA0In1dfV0sCiAgICAgICAgIjIiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLnjrDku6PoqIDmg4UiLCJ2IjoiMSJ9LHsibiI6IuWPpOS7o+iogOaDhSIsInYiOiIyIn0seyJuIjoi5bm75oOz6KiA5oOFIiwidiI6IjQifSx7Im4iOiLnp43nlLDnu4/llYYiLCJ2IjoiMTYifV19XSwKICAgICAgICAiMyI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuaWh+WtpuiJuuacryIsInYiOiIyNDAifSx7Im4iOiLkurrmlofnp5HnpL4iLCJ2IjoiMjQxIn0seyJuIjoi57uP566h5Yqx5b+XIiwidiI6IjI0MiJ9LHsibiI6Iue7j+WFuOaWh+WtpiIsInYiOiIyNDMifSx7Im4iOiLkurrniankvKDorrAiLCJ2IjoiMjQ3In0seyJuIjoi5bCR5YS/5pWZ6IKyIiwidiI6IjI1OCJ9LHsibiI6IuWPpOS7o+iogOaDhSIsInYiOiIyNTkifSx7Im4iOiLnjrDku6PoqIDmg4UiLCJ2IjoiMjYwIn0seyJuIjoi5oKs55aR5o6o55CGIiwidiI6IjI2MiJ9LHsibiI6IuWOhuWPsuS8oOiusCIsInYiOiIyNjQifSx7Im4iOiLpnZLmmKXmloflraYiLCJ2IjoiMjY1In0seyJuIjoi546w5a6e5bCP6K+0IiwidiI6IjI2NiJ9LHsibiI6IuS7meS+oOWlh+e8mCIsInYiOiIyNzYifSx7Im4iOiLku5nkvqDlpYflubsiLCJ2IjoiMjg4In0seyJuIjoi5q2m5L6g5bCP6K+0IiwidiI6IjI4OSJ9LHsibiI6IueOsOS7o+WGm+aXhSIsInYiOiIyOTAifV19XQogICAgfSwKICAgIGZpbHRlcl91cmw6ICJ7e2ZsLnR5cGV9fSIsCiAgICBmaWx0ZXJfZGVmOiB7fSwKICAgIGhlYWRlcnM6IHsnVXNlci1BZ2VudCc6ICdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTM5LjAuMC4wIFNhZmFyaS81MzcuMzYnfSwKICAgIHNpZ25faGVhZGVyczogewogICAgICAgICJhcHAtdmVyc2lvbiI6ICI1MTExMCIsICJwbGF0Zm9ybSI6ICJhbmRyb2lkIiwgInJlZyI6ICIwIiwgIkFVVEhPUklaQVRJT04iOiAiIiwKICAgICAgICAiYXBwbGljYXRpb24taWQiOiAiY29tLioqKioucmVhZGVyIiwgIm5ldC1lbnYiOiAiMSIsICJjaGFubmVsIjogInVua25vd24iLCAicW0tcGFyYW1zIjogIiIKICAgIH0sCiAgICB0aW1lb3V0OiAxMDAwMCwKICAgIHBsYXlfcGFyc2U6IHRydWUsCgogICAgYXBpUmVxdWVzdDogYXN5bmMgZnVuY3Rpb24gKGVuZHBvaW50LCBwYXJhbXMgPSB7fSwgb3B0aW9ucyA9IHt9KSB7CiAgICAgICAgY29uc3QgaG9zdCA9IG9wdGlvbnMuaG9zdCB8fCB0aGlzLmhvc3Q7CiAgICAgICAgcGFyYW1zLmltZWlfaXAgPSBwYXJhbXMuaW1laV9pcCB8fCAnMjkzNzM1NzEwNyc7CiAgICAgICAgcGFyYW1zLnNpZ24gPSBnZXRTaWduU3RyKHBhcmFtcyk7CiAgICAgICAgY29uc3QgdXJsID0gYnVpbGRVcmwoYCR7aG9zdH0ke2VuZHBvaW50fWAsIHBhcmFtcyk7CiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QodXJsLCB7CiAgICAgICAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyB8fCB0aGlzLnNpZ25faGVhZGVycywKICAgICAgICAgICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCB8fCAnR0VUJwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3BvbnNlKTsKICAgIH0sCiAgICAKICAgIHJlcXVlc3Q6IGFzeW5jIGZ1bmN0aW9uICh1cmwsIG9iaikgewogICAgICAgIG9iaiA9IG9iaiB8fCB7fTsKICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IF9mZXRjaCh1cmwsIHsKICAgICAgICAgICAgbWV0aG9kOiBvYmoubWV0aG9kIHx8ICdHRVQnLAogICAgICAgICAgICBoZWFkZXJzOiBvYmouaGVhZGVycyB8fCB0aGlzLmhlYWRlcnMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpOwogICAgfSwKCiAgICDpooTlpITnkIY6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICB0aGlzLnNpZ25faGVhZGVycy5zaWduID0gZ2V0U2lnblN0cih0aGlzLnNpZ25faGVhZGVycyk7CiAgICB9LAoKICAgIOS4gOe6pzogYXN5bmMgZnVuY3Rpb24gKHRpZCwgcGcsIGZpbHRlciwgZXh0ZW5kKSB7CiAgICAgICAgbGV0IGQgPSBbXTsKICAgICAgICBjb25zdCBjYXRlTWFwID0geycxJzonMjAyJywgJzInOicxJywgJzMnOicyNDAnfTsKICAgICAgICBjb25zdCB0eXBlSWQgPSB0aWQgIT09ICctMScgPyB0aWQgOiAnMic7CiAgICAgICAgbGV0IGNhdGVnb3J5X2lkID0gY2F0ZU1hcFt0eXBlSWRdIHx8ICcxJzsKICAgICAgICBjb25zdCB2YWxpZFN1YlR5cGVzU2V0ID0gbmV3IFNldCgpOwogICAgICAgIE9iamVjdC52YWx1ZXModGhpcy5maWx0ZXIpLmZvckVhY2goZmlsdGVyR3JvdXAgPT4gewogICAgICAgICAgICBmaWx0ZXJHcm91cC5mb3JFYWNoKGl0ZW0gPT4gewogICAgICAgICAgICAgICAgaXRlbS52YWx1ZS5mb3JFYWNoKHN1YlR5cGUgPT4gewogICAgICAgICAgICAgICAgICAgIHZhbGlkU3ViVHlwZXNTZXQuYWRkKHN1YlR5cGUudik7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSk7CiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgaWYgKGV4dGVuZD8udHlwZSAmJiB2YWxpZFN1YlR5cGVzU2V0LmhhcyhleHRlbmQudHlwZSkpIHsKICAgICAgICAgICAgY2F0ZWdvcnlfaWQgPSBleHRlbmQudHlwZTsKICAgICAgICB9IGVsc2UgaWYgKGZpbHRlciAmJiB2YWxpZFN1YlR5cGVzU2V0LmhhcyhmaWx0ZXIpKSB7CiAgICAgICAgICAgIGNhdGVnb3J5X2lkID0gZmlsdGVyOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBjb25zdCBwYXJhbXMgPSB7CiAgICAgICAgICAgIGdlbmRlcjogdHlwZUlkLAogICAgICAgICAgICBjYXRlZ29yeV9pZDogY2F0ZWdvcnlfaWQsCiAgICAgICAgICAgIG5lZWRfZmlsdGVyczogJzEnLAogICAgICAgICAgICBwYWdlOiBwZyB8fCAnMScsCiAgICAgICAgICAgIG5lZWRfY2F0ZWdvcnk6ICcxJwogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgY29uc3QganNvbiA9IGF3YWl0IHRoaXMuYXBpUmVxdWVzdCgnL2FwaS92NC9jYXRlZ29yeS9nZXQtbGlzdCcsIHBhcmFtcyk7CiAgICAgICAgaWYgKGpzb24/LmRhdGE/LmJvb2tzKSB7CiAgICAgICAgICAgIGQgPSBqc29uLmRhdGEuYm9va3MubWFwKGl0ID0+ICh7CiAgICAgICAgICAgICAgICB0aXRsZTogaXQudGl0bGUsCiAgICAgICAgICAgICAgICB1cmw6IGAke3RoaXMuaG9zdH0vYXBpL3Y0L2Jvb2svZGV0YWlsP2lkPSR7aXQuaWR9YCwKICAgICAgICAgICAgICAgIGRlc2M6IGl0LmF1dGhvciwKICAgICAgICAgICAgICAgIHBpY191cmw6IGl0LmltYWdlX2xpbmssCiAgICAgICAgICAgICAgICBjb250ZW50OiBpdC5pbnRybwogICAgICAgICAgICB9KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXRSZXN1bHQoZCk7CiAgICB9LAoKICAgIOS6jOe6pzogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBWT0QgPSB7fTsKICAgICAgICBsZXQgYm9va0lkID0gdGhpcy5pbnB1dC5tYXRjaCgvaWQ9KFxkKykvKVsxXTsKICAgICAgICBjb25zdCBkZXRhaWxKc29uID0gYXdhaXQgdGhpcy5hcGlSZXF1ZXN0KCcvYXBpL3Y0L2Jvb2svZGV0YWlsJywgewogICAgICAgICAgICBpZDogYm9va0lkLAogICAgICAgICAgICB0ZWVueV9tb2RlOiAnMCcKICAgICAgICB9KTsKICAgICAgICBpZiAoZGV0YWlsSnNvbj8uZGF0YT8uYm9vaykgewogICAgICAgICAgICBsZXQgYm9vayA9IGRldGFpbEpzb24uZGF0YS5ib29rOwogICAgICAgICAgICBWT0QgPSB7CiAgICAgICAgICAgICAgICB2b2RfbmFtZTogYm9vay50aXRsZSwKICAgICAgICAgICAgICAgIHR5cGVfbmFtZTogYm9vay5ib29rX3RhZ19saXN0Py5tYXAodGFnID0+IHRhZy50aXRsZSkuam9pbignLCcpIHx8ICcnLAogICAgICAgICAgICAgICAgdm9kX3BpYzogYm9vay5pbWFnZV9saW5rLAogICAgICAgICAgICAgICAgdm9kX2NvbnRlbnQ6IGJvb2suaW50cm8sCiAgICAgICAgICAgICAgICB2b2RfcmVtYXJrczogYm9vay5sYXRlc3RfY2hhcHRlcl90aXRsZSwKICAgICAgICAgICAgICAgIHZvZF95ZWFyOiAnJywgdm9kX2FyZWE6ICcnLAogICAgICAgICAgICAgICAgdm9kX2FjdG9yOiBib29rLmF1dGhvciwgdm9kX2RpcmVjdG9yOiBib29rLmF1dGhvciwKICAgICAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfpmIXor7vliqnmiYsnCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGNvbnN0IHRvY0pzb24gPSBhd2FpdCB0aGlzLmFwaVJlcXVlc3QoJy9hcGkvdjEvY2hhcHRlci9jaGFwdGVyLWxpc3QnLCB7CiAgICAgICAgICAgICAgICBpZDogYm9vay5pZAogICAgICAgICAgICB9LCB7CiAgICAgICAgICAgICAgICBob3N0OiB0aGlzLmNoYXB0ZXJIb3N0CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAodG9jSnNvbj8uZGF0YT8uY2hhcHRlcl9saXN0cykgewogICAgICAgICAgICAgICAgVk9ELnZvZF9wbGF5X3VybCA9IHRvY0pzb24uZGF0YS5jaGFwdGVyX2xpc3RzLm1hcChjaGFwdGVyID0+IAogICAgICAgICAgICAgICAgICAgIGAke2NoYXB0ZXIudGl0bGV9JCR7Ym9vay5pZH1AQCR7Y2hhcHRlci5pZH1AQCR7Y2hhcHRlci50aXRsZX1gCiAgICAgICAgICAgICAgICApLmpvaW4oJyMnKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gVk9EOwogICAgfSwKCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgZCA9IFtdOwogICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCB0aGlzLmFwaVJlcXVlc3QoJy9hcGkvdjUvc2VhcmNoL3dvcmRzJywgewogICAgICAgICAgICBnZW5kZXI6ICczJywKICAgICAgICAgICAgcGFnZTogdGhpcy5NWV9QQUdFLAogICAgICAgICAgICB3ZDogdGhpcy5LRVkKICAgICAgICB9KTsKICAgICAgICBpZiAoanNvbj8uZGF0YT8uYm9va3MpIHsKICAgICAgICAgICAgZCA9IGpzb24uZGF0YS5ib29rcy5tYXAoaXQgPT4gKHsKICAgICAgICAgICAgICAgIHRpdGxlOiBpdC5vcmlnaW5hbF90aXRsZSwKICAgICAgICAgICAgICAgIGRlc2M6IGl0LmF1dGhvciwKICAgICAgICAgICAgICAgIHBpY191cmw6IGl0LmltYWdlX2xpbmssCiAgICAgICAgICAgICAgICB1cmw6IGAke3RoaXMuaG9zdH0vYXBpL3Y0L2Jvb2svZGV0YWlsP2lkPSR7aXQuaWR9YCwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGl0LmludHJvCiAgICAgICAgICAgIH0pKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNldFJlc3VsdChkKTsKICAgIH0sCgogICAgbGF6eTogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBbYm9va0lkLCBjaGFwdGVySWQsIHRpdGxlXSA9IHRoaXMuaW5wdXQuc3BsaXQoJ0BAJyk7CiAgICAgICAgbGV0IGNvbnRlbnQgPSAn5YaF5a655Yqg6L295aSx6LSlJzsKICAgICAgICBjb25zdCBqc29uID0gYXdhaXQgdGhpcy5hcGlSZXF1ZXN0KCcvYXBpL3YxL2NoYXB0ZXIvY29udGVudCcsIHsKICAgICAgICAgICAgaWQ6IGJvb2tJZCwKICAgICAgICAgICAgY2hhcHRlcklkCiAgICAgICAgfSwgewogICAgICAgICAgICBob3N0OiB0aGlzLmNoYXB0ZXJIb3N0CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGpzb24/LmRhdGE/LmNvbnRlbnQpIGNvbnRlbnQgPSBkZWNvZGVDb250ZW50KGpzb24uZGF0YS5jb250ZW50KTsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICBwYXJzZTogMCwKICAgICAgICAgICAgdXJsOiBgbm92ZWw6Ly8ke0pTT04uc3RyaW5naWZ5KHt0aXRsZSwgY29udGVudH0pfWAsCiAgICAgICAgICAgIGpzOiAnJwogICAgICAgIH07CiAgICB9Cn07CgpmdW5jdGlvbiBnZXRTaWduU3RyKHBhcmFtcykgewogICAgY29uc3Qgc2lnbl9rZXkgPSAiZDNkR2lKYzY1MWdTUTh3MSI7CiAgICByZXR1cm4gbWQ1KE9iamVjdC5rZXlzKHBhcmFtcykuc29ydCgpLnJlZHVjZSgocHJlLCBuKSA9PiBwcmUgKyBuICsgIj0iICsgcGFyYW1zW25dLCAiIikgKyBzaWduX2tleSk7Cn0KCmZ1bmN0aW9uIGRlY29kZUNvbnRlbnQoY29udGVudCkgewogICAgbGV0IGtleSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKCIyNDJjY2I4MjMwZDcwOWUxIik7CiAgICBsZXQgaXZFbmNEYXRhID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5wYXJzZShjb250ZW50KTsKICAgIGxldCBpdiA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKGl2RW5jRGF0YS53b3Jkcy5zbGljZSgwLCA0KSk7CiAgICBsZXQgZW5jcnlwdGVkID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoaXZFbmNEYXRhLndvcmRzLnNsaWNlKDQpKTsKICAgIGxldCBkZWNyeXB0ZWQgPSBDcnlwdG9KUy5BRVMuZGVjcnlwdCh7Y2lwaGVydGV4dDogZW5jcnlwdGVkfSwga2V5LCB7CiAgICAgICAgaXYsIG1vZGU6IENyeXB0b0pTLm1vZGUuQ0JDLCBwYWRkaW5nOiBDcnlwdG9KUy5wYWQuUGtjczcKICAgIH0pOwogICAgcmV0dXJuIGRlY3J5cHRlZC50b1N0cmluZyhDcnlwdG9KUy5lbmMuVXRmOCk7Cn0= \ No newline at end of file From f29420d8310ba990173290e3d6bde4657af2948c Mon Sep 17 00:00:00 2001 From: Taois Date: Fri, 16 Jan 2026 10:58:19 +0800 Subject: [PATCH 25/99] fix:some source --- ...\346\274\253\347\224\273[\347\224\273].js" | 252 ++++++++++++++++++ ...\346\274\253\347\224\273[\347\224\273].js" | 68 +++-- ...\345\212\251\346\211\213[\344\271\246].js" | 12 + 3 files changed, 305 insertions(+), 27 deletions(-) create mode 100644 "spider/catvod/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" diff --git "a/spider/catvod/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" "b/spider/catvod/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" new file mode 100644 index 00000000..1afdc504 --- /dev/null +++ "b/spider/catvod/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" @@ -0,0 +1,252 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 0, + title: '番茄漫画', + '类型': '漫画', + lang: 'ds' +}) +*/ +import cheerio from 'assets://js/lib/cheerio.min.js'; + +let HOST = 'https://qkfqapi.vv9v.cn'; +let UA = { + "User-Agent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36" +}; + +async function request(url, obj) { + if (!obj) { + obj = { + headers: UA, + timeout: 5000 + } + } + const response = await req(url, obj); + return response.content; +} + +function init(cfg) { + const ext = cfg.ext; + console.log('番茄漫画源初始化'); + console.log('初始化完成'); +} + +async function home(filter) { + try { + let html = await request('https://qkfqapi.vv9v.cn/api/discover/style?tab=漫画&source_type=男频'); + let json = JSON.parse(html); + let data = json.data; + let d = []; + data.forEach((it) => { + if (it.url && it.url.trim() !== '') { + d.push({ + type_name: it.title, + type_id: it.url, + }); + } + }); + return JSON.stringify({ + 'class': d + }); + } catch (error) { + console.log('home函数错误:', error); + } +} + + +async function homeVod(params) { + try { + let url = HOST + '/api/discover?tab=漫画&type=7&gender=2&genre_type=110&page=1'; + let html = await request(url); + let json = JSON.parse(html); + + if (json && json.data) { + let data = json.data.data || json.data; + let d = []; + + data.forEach((item) => { + if (item && item.book_name) { + d.push({ + vod_name: item.book_name, + vod_id: item.book_id || item.id, + vod_pic: item.thumb_url || item.cover, + vod_remarks: item.author || item.category || '', + vod_content: item.abstract || item.description || '' + }); + } + }); + + return JSON.stringify({ + list: d + }); + } + } catch (error) { + console.log('首页推荐请求错误:', error); + } +} + +async function category(tid, pg, filter, extend) { + try { + let url = tid; + let html = await request(url); + let json = JSON.parse(html); + + if (json && json.data) { + let data = json.data.data || json.data; + let d = []; + + data.forEach((item) => { + if (item && item.book_name) { + d.push({ + vod_name: item.book_name, + vod_id: item.book_id || item.id, + vod_pic: item.thumb_url || item.cover, + vod_remarks: item.author || item.category || '', + vod_content: item.abstract || item.description || '' + }); + } + }); + + if (d.length > 0) { + return JSON.stringify({ + list: d, + page: pg, + pagecount: 999, + limit: 20, + total: 999 + }); + } + } + } catch (error) { + console.log('分类请求错误:', error); + } +} + +async function detail(vod_url) { + try { + let detailUrl = HOST + '/api/detail?book_id=' + vod_url; + let json = JSON.parse(await request(detailUrl)); + + if (json?.data?.data) { + let data = json.data.data; + let vod = { + vod_name: data.book_name || '', + vod_id: vod_url, + type_name: data.category || '', + vod_pic: data.thumb_url || '', + vod_content: data.abstract || '', + vod_remarks: data.sub_info || '', + vod_director: data.author || '', + vod_play_from: '番茄漫画', + vod_play_url: '' + }; + + let chapterUrl = HOST + '/api/book?book_id=' + vod_url; + let chapterJson = JSON.parse(await request(chapterUrl)); + if (chapterJson?.data?.data) { + let bookInfo = chapterJson.data.data; + let list = bookInfo.chapterListWithVolume.flat(); + + let urls = []; + list.forEach((it) => { + if (it && it.title && it.itemId) { + urls.push(it.title + '$' + it.itemId + '@' + it.title); + } + }); + vod.vod_play_url = urls.join('#'); + } + + return JSON.stringify({list: [vod]}); + } + } catch (error) { + console.log('详情请求错误:', error); + } +} + +async function play(flag, id, flags) { + try { + let itemId = id; + let title = ''; + + if (id.includes('@')) { + let parts = id.split('@'); + itemId = parts[0]; + title = parts[1] || ''; + } + + let url = HOST + '/api/content?tab=漫画&item_id=' + itemId + '&show_html=0'; + let html = await request(url); + let json = JSON.parse(html); + let images = json.data.images; + images = pdfa(images, 'img'); + let pics = []; + images.forEach((img) => { + let pic = pdfh(img, 'img&&src'); + pics.push(pic); + }); + + if (pics.length > 0) { + return JSON.stringify({ + parse: 0, + url: 'pics://' + pics.join('&&') + }); + } + } catch (error) { + console.log('播放 请求错误:', error); + } +} + +async function search(wd, quick) { + try { + let searchUrl = HOST + '/api/search?key=' + encodeURIComponent(wd) + '&tab_type=8&offset=0'; + let html = await request(searchUrl); + let json = JSON.parse(html); + + if (json && json.data) { + let searchTabs = json.data.search_tabs || []; + let bookList = []; + + if (searchTabs.length > 3 && searchTabs[3].data) { + bookList = searchTabs[3].data; + } else if (json.data.data) { + bookList = json.data.data; + } + + let d = []; + bookList.forEach((item) => { + let book = item.book_data ? item.book_data[0] : item; + if (book && book.book_name) { + d.push({ + vod_name: book.book_name, + vod_id: book.book_id, + vod_pic: book.thumb_url || '', + vod_remarks: book.author || '', + vod_content: book.book_abstract || book.abstract || '' + }); + } + }); + + return JSON.stringify({ + list: d + }); + } + } catch (error) { + console.log('搜索请求错误:', error); + } +} + +function proxy(params) { + return [200, 'text/plain;charset=utf-8', '番茄漫画源代理测试', null]; +} + +export default { + init: init, + home: home, + homeVod: homeVod, + category: category, + detail: detail, + play: play, + search: search, + proxy: proxy, +} \ No newline at end of file diff --git "a/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" "b/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" index 230432e8..04519808 100644 --- "a/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" +++ "b/spider/js/\347\225\252\350\214\204\346\274\253\347\224\273[\347\224\273].js" @@ -13,7 +13,8 @@ var rule = { 类型: '漫画', title: '番茄漫画', host: 'https://qkfqapi.vv9v.cn', - url: '', + homeUrl: '/api/discover/style?tab=漫画', + url: 'fyclass', searchUrl: '/api/search?key=**&tab_type=8&offset=((fypage-1)*10)', detailUrl: '/api/detail?book_id=fyid', headers: {'User-Agent': 'UC_UA'}, @@ -22,11 +23,19 @@ var rule = { filterable: 0, double: true, play_parse: true, - limit: 12, - // class_parse: async function () { - // let {input, pdfa, pdfh, pd} = this; - // return {} - // }, + limit: 10, + class_parse: async function () { + let {input} = this; + let html = await request(input); + let data = html.parseX.data; + let d = data.filter(item => item.url.trim()).map((it) => { + return { + type_name: it.title, + type_id: it.url, + } + }); + return {class: d} + }, lazy: async function () { let {input, pdfa, pdfh} = this; let title = input.split('@')[1]; @@ -42,24 +51,38 @@ var rule = { } return {parse: 0, url: 'pics://' + pics.join('&&')} }, + parseList(html) { + let data = html.parseX.data; + data = data.data || data; + let d = []; + data.forEach((item) => { + if (item && item.book_name) { + d.push({ + vod_name: item.book_name, + vod_id: item.book_id || item.id, + vod_pic: item.thumb_url || item.cover, + vod_remarks: item.author || item.category || '', + vod_content: item.abstract || item.description || '' + }); + } + }); + return d + }, 推荐: async function () { - return [{ - vod_id: 'only_search', - vod_name: '纯搜索源哦!', - vod_tag: 'action', - vod_pic: this.publicUrl + '/images/icon_cookie/搜索.jpg' - }]; + let {HOST} = this; + let url = HOST + '/api/discover?tab=漫画&type=7&gender=2&genre_type=110&page=1'; + let html = await request(url); + return this.parseList(html); }, - 一级: async function () { - return []; + 一级: async function (tid, pg, filter, extend) { + input = jinja.render(tid, {page: pg}); + let html = await request(input); + return this.parseList(html); }, 二级: async function () { let {input, orId} = this; - // log('input', input); - // log('orId', orId); let html = await request(input); - let json = JSON.parse(html); - let data = json.data.data; + let data = html.parseX.data.data; let VOD = {}; VOD.vod_name = data.book_name; VOD.type_name = data.category; @@ -83,10 +106,6 @@ var rule = { }, 搜索: async function () { let {input, MY_PAGE} = this; - // if (Number(MY_PAGE) > 1) { - // return [] - // } - print(input) let html = await request(input); let json = JSON.parse(html); let data = json.data.search_tabs[3].data; @@ -104,9 +123,4 @@ var rule = { } return setResult(d) }, - action: async function (action, value) { - if (action === 'only_search') { - return '此源为纯搜索源,你直接全局搜索这个源或者使用此页面的源内搜索就好了' - } - } } \ No newline at end of file diff --git "a/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" index 40f61d11..fed18169 100644 --- "a/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" +++ "b/spider/js/\351\230\205\350\257\273\345\212\251\346\211\213[\344\271\246].js" @@ -1,3 +1,15 @@ +/* +@header({ + searchable: 2, + filterable: 1, + quickSearch: 0, + title: '阅读助手[书]', + author: 'EylinSir', + '类型': '小说', + lang: 'ds' +}) +*/ + var rule = { 类型: '小说', author: 'EylinSir', From 566e6abfd343d1a4a799bde1cab3ba45daa54db4 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 21:02:36 +0800 Subject: [PATCH 26/99] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8E=BB=E8=AF=BB?= =?UTF-8?q?=E4=B9=A6[=E4=B9=A6].js=E6=96=87=E4=BB=B6=E7=9A=84=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E6=9B=BF=E6=8D=A2=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\350\257\273\344\271\246[\344\271\246].js" | 139 ++++++++---------- 1 file changed, 60 insertions(+), 79 deletions(-) diff --git "a/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" index 86b8b485..44b8f662 100644 --- "a/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" +++ "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" @@ -29,38 +29,23 @@ var rule = { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36' }, - request: async function (url, obj) { - obj = obj || {}; - try { - const response = await _fetch(url, { - method: obj.method || 'GET', - headers: obj.headers || this.headers - }); - return response.text(); - } catch (err) { - return ''; - } - }, - + 一级: async function () { let {input, pdfa, pdfh, pd} = this; - let url = input.startsWith('http') ? input : this.host + '/book/' + input + '/0/1.html'; - let html = await this.request(url); + let url = input.startsWith('http') ? input : `${this.host}/book/${input}/0/1.html`; + let html = await request(url); let d = []; let items = pdfa(html, '.blockcontent .c_row') || pdfa(html, '.c_row') || []; for (let item of items) { let title = pdfh(item, '.c_subject a:eq(1)&&Text'); - let itemUrl = pd(item, '.c_subject a:eq(1)&&href'); - if (!title || !itemUrl) continue; - let remarks = pdfh(item, '.c_tag span:eq(1)&&Text') || ''; - let pic = pd(item, 'img&&src') || ''; - let content = pdfh(item, '.c_description&&Text') || ''; + let url = pd(item, '.c_subject a:eq(1)&&href'); + if (!title || !url) continue; d.push({ - title: title, - url: itemUrl, - desc: remarks, - pic_url: pic, - content: content, + title, + url, + desc: pdfh(item, '.c_tag span:eq(1)&&Text') || '', + pic_url: pd(item, 'img&&src') || '', + content: pdfh(item, '.c_description&&Text') || '', }); } return setResult(d); @@ -68,58 +53,52 @@ var rule = { 二级: async function () { let {input, pdfa, pdfh, pd} = this; - let html = await this.request(input); - let VOD = {}; - VOD.vod_name = pdfh(html, '[property="og:novel:book_name"]&&content') || ''; - VOD.type_name = ''; - VOD.vod_pic = pd(html, '.divbox.cf img&&src') || ''; - VOD.vod_content = pdfh(html, '.tabcontent .tabvalue:eq(0)&&Text') || ''; - VOD.vod_remarks = pdfh(html, 'h3 a&&Text') || ''; - VOD.vod_year = ''; - VOD.vod_area = ''; - VOD.vod_actor = pdfh(html, '[property="og:novel:author"]&&content') || ''; - VOD.vod_director = VOD.vod_actor; - VOD.vod_play_from = '去读书网'; - let toc_url = pd(html, 'a:contains(点击阅读)&&href') || ''; - if (toc_url && !toc_url.startsWith('http')) { - toc_url = this.host + toc_url; - } - let toc_html = toc_url ? await this.request(toc_url) : ''; + let html = await request(input); + let VOD = { + vod_name: pdfh(html, '[property="og:novel:book_name"]&&content') || '', + type_name: '', + vod_pic: pd(html, '.divbox.cf img&&src') || '', + vod_content: pdfh(html, '.tabcontent .tabvalue:eq(0)&&Text') || '', + vod_remarks: pdfh(html, 'h3 a&&Text') || '', + vod_year: '', + vod_area: '', + vod_actor: pdfh(html, '[property="og:novel:author"]&&content') || '', + vod_director: '', + vod_play_from: '去读书网', + vod_play_url: '' + }; + VOD.vod_director = VOD.vod_actor; // 复用作者信息 + let tocUrl = pd(html, 'a:contains(点击阅读)&&href') || ''; + tocUrl = tocUrl && !tocUrl.startsWith('http') ? `${this.host}${tocUrl}` : tocUrl; + let tocHtml = tocUrl ? await request(tocUrl) : ''; let chapters = []; - let chapterItems = pdfa(toc_html, '.index li') || []; - for (let chapter of chapterItems) { - let title = pdfh(chapter, 'a&&Text'); - let chapter_url = pd(chapter, 'a&&href'); - if (!title || !chapter_url) continue; - if (!chapter_url.startsWith('http')) { - chapter_url = this.host + chapter_url; - } - chapters.push(title + '$' + chapter_url); + let chs = pdfa(tocHtml, '.index li') || []; + for (let ch of chs) { + let title = pdfh(ch, 'a&&Text'); + let chUrl = pd(ch, 'a&&href'); + if (!title || !chUrl) continue; + chUrl = chUrl.startsWith('http') ? chUrl : `${this.host}${chUrl}`; + chapters.push(`${title}$${chUrl}`); } VOD.vod_play_url = chapters.join('#'); return VOD; }, 搜索: async function () { - let {KEY, pdfa, pdfh, pd} = this; - let url = this.host + this.searchUrl.replace('**', encodeURIComponent(KEY)); - let html = await this.request(url); - if (!html) { - url = this.host + '/modules/article/search.php?q=' + encodeURIComponent(KEY); - html = await this.request(url); - } + let {input, pdfa, pdfh, pd} = this; + let html = await request(input); let d = []; let items = pdfa(html, '#jieqi_page_contents .c_row') || []; for (let item of items) { let title = pdfh(item, '.c_subject a&&Text'); - let itemUrl = pd(item, '.c_subject a&&href'); - if (!title || !itemUrl) continue; - itemUrl = itemUrl.startsWith('http') ? itemUrl : this.host + itemUrl; + let url = pd(item, '.c_subject a&&href'); + if (!title || !url) continue; + url = url.startsWith('http') ? url : `${this.host}${url}`; let pic = pd(item, 'img&&src') || ''; - pic = pic.startsWith('http') ? pic : this.host + pic; + pic = pic.startsWith('http') ? pic : `${this.host}${pic}`; d.push({ - title: title, - url: itemUrl, + title, + url, desc: pdfh(item, '.c_tag span:eq(1)&&Text') || '', pic_url: pic, content: '', @@ -127,29 +106,31 @@ var rule = { } return setResult(d); }, - + // 懒加载解析(章节内容) lazy: async function () { let {input, pdfh} = this; - let html = await this.request(input); + let html = await request(input); let title = pdfh(html, 'h1&&Text') || ''; let content = pdfh(html, '#acontent&&Html') || ''; if (content) { - content = content.replace(/]*?>.*?<\/script>/gs, '') - .replace(/<\/p>/g, '\n\n') - .replace(/]*?>/g, '\n') - .replace(/<[^>]*?>/g, '') - .replace(/去读书推荐各位书友阅读:.*|去读书 www\.qudushu\.la|如果您中途有事离开,请按.*以便以后接着观看!/g, '') - .replace(/[()]/g, '') - .replace(/ /g, ' ') - .replace(/[ \t]+/g, ' ') - .replace(/\n[ \t]+|[ \t]+\n/g, '\n') - .replace(/\n+/g, '\n\n') - .trim(); + const replaceRules = [ + [/]*?>[\s\S]*?<\/script>/gi, ''], + [/<\/p>|/g, '\n'], + [/<[^>]*?>/g, ''], + [/去读书推荐各位书友阅读:.*|去读书 www\.qudushu\.la|如果您中途有事离开,请按.*以便以后接着观看!/g, ''], + [/ |[ \t]+/g, ' '], + [/\n[ \t]*\n+/g, '\n'] + ]; + replaceRules.forEach(([reg, val]) => content = content.replace(reg, val)); + content = content.trim(); + if (content.startsWith(title)) { + content = content.replace(title, '').trim(); + } } return { parse: 0, - url: 'novel://' + JSON.stringify({title, content}), + url: `novel://${JSON.stringify({title, content})}`, js: '' }; } -}; +}; \ No newline at end of file From 7689b51afe0936a6f9f193dc0359cefb233fe366 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 21:04:24 +0800 Subject: [PATCH 27/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0jx/web1.js=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jx/web1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jx/web1.js b/jx/web1.js index e190d820..6c870d83 100644 --- a/jx/web1.js +++ b/jx/web1.js @@ -63,7 +63,7 @@ const jx = { * 添加url属性直接暴露api,不走系统。建议web解析才写这个属性,json解析隐藏起来 * @type {string} */ - url: 'https://bfq.cfwlgzs.cn/player?url=', + url: 'https://www.ckplayer.vip/jiexi/?url=', }; /** From ba268e539b089c8a0a29210f55c92b78c5be88e6 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 22:48:49 +0800 Subject: [PATCH 28/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8A=AA=E5=8A=AA?= =?UTF-8?q?=E4=B9=A6=E5=9D=8A[=E4=B9=A6].js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...16\273\350\257\273\344\271\246[\344\271\246].js" | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git "a/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" index 44b8f662..7a0c87f6 100644 --- "a/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" +++ "b/spider/js/\345\216\273\350\257\273\344\271\246[\344\271\246].js" @@ -26,9 +26,7 @@ var rule = { filterable: 0, timeout: 10000, play_parse: true, - headers: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36' - }, + headers: { 'User-Agent': 'MOBILE_UA' }, 一级: async function () { let {input, pdfa, pdfh, pd} = this; @@ -56,16 +54,11 @@ var rule = { let html = await request(input); let VOD = { vod_name: pdfh(html, '[property="og:novel:book_name"]&&content') || '', - type_name: '', vod_pic: pd(html, '.divbox.cf img&&src') || '', vod_content: pdfh(html, '.tabcontent .tabvalue:eq(0)&&Text') || '', vod_remarks: pdfh(html, 'h3 a&&Text') || '', - vod_year: '', - vod_area: '', vod_actor: pdfh(html, '[property="og:novel:author"]&&content') || '', - vod_director: '', - vod_play_from: '去读书网', - vod_play_url: '' + vod_play_from: '去读书网' }; VOD.vod_director = VOD.vod_actor; // 复用作者信息 let tocUrl = pd(html, 'a:contains(点击阅读)&&href') || ''; @@ -106,7 +99,7 @@ var rule = { } return setResult(d); }, - // 懒加载解析(章节内容) + lazy: async function () { let {input, pdfh} = this; let html = await request(input); From 435e9137c356a2200ff17966dbf714c803dfeffb Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Fri, 16 Jan 2026 23:00:43 +0800 Subject: [PATCH 29/99] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B9=90=E4=B9=90?= =?UTF-8?q?=E4=B9=A6=E6=88=BF[=E4=B9=A6].js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\344\271\246\345\235\212[\344\271\246].js" | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 "spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" diff --git "a/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" "b/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" new file mode 100644 index 00000000..55c284fd --- /dev/null +++ "b/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" @@ -0,0 +1,136 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 1, + title: '努努书坊[书]', + author: 'EylinSir', + '类型': '小说', + logo: 'https://www.nunubook.com/favicon.ico', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '小说', + author: 'EylinSir', + title: '努努书坊[书]', + host: 'https://www.nunubook.com', + url: '/fyclass/##fypage', + logo: 'https://www.nunubook.com/favicon.ico', + class_name: '玄幻小说&魔幻小说&悬疑小说&历史架空&都市小说&言情小说&武侠小说&官场小说&现代小说&战争军事&侦探推理&外国小说&纪实小说&诗歌戏曲&宗教哲学&文学理论&寓言童话&科普学习&社会心理&作品集&传记回忆&杂文随笔', + class_url: 'xuanhuan&mohuan&xuanyi&lishi&dushi&yanqing&wuxia&guanchang&xiandaixiaoshuo&zhanzhengjunshi&zhentantuili&waiguo&jishi&shigexiqu&zhexue&wenxuelilun&yuyantonghua&kepuxuexi&shehuixinli&zuopinji&zhuanjihuiyi&zawen', + searchUrl: '/e/search/index.php?tbname=bookname&show=title&tempid=1&keyboard=**', + searchable: 1, + quickSearch: 1, + filterable: 0, + timeout: 10000, + play_parse: true, + headers: { 'User-Agent': 'MOBILE_UA' }, + + 一级: async function () { + let [cateUrl, pg] = this.input.split('##'); + let list = []; + let cateKey = cateUrl.split('/').filter(Boolean).pop() || ''; + let cl = this.class_url.split('&').findIndex(k => k === cateKey) + 1 || undefined; + if (pg === '1') { + let html = await request(cateUrl); + let selectors = ['.listBig-li', 'li.listBig-li', '.book-item', '.list-item']; + let items = selectors.map(sel => this.pdfa(html, sel)).find(Boolean); + items?.forEach(item => { + let urlSelectors = ['a:eq(0)&&href', 'a&&href']; + let url = urlSelectors.map(sel => this.pd(item, sel)).find(Boolean) || this.pdfh(item, 'a&&href'); + if (url) { + url = url.startsWith('http') ? url : `${this.host}${url}`; + let title = this.pdfh(item, 'h3&&Text') || this.pdfh(item, 'h2&&Text') || '未知标题'; + let desc = this.pdfh(item, 'p:eq(0)&&Text') || '无简介'; + list.push({ + title, + url, + desc, + pic_url: this.pd(item, 'img&&src') || '', + content: this.pdfh(item, '.text&&Text') || desc + }); + } + }); + } else if (cl) { + let apiUrl = `${this.host}/e/extend/more/lsmore.php?page=${pg}&line=10&cl=${cl}`; + let json = JSON.parse(await request(apiUrl)); + list.push(...json.map(item => ({ + title: item.title, + url: item.url, + pic_url: item.pic, + desc: item.smalltext, + content: `${item.smalltext}\n作者:${item.writer}` + }))); + } + return setResult(list); + }, + + 二级: async function () { + let html = await request(this.input); + let VOD = { + vod_name: this.pdfh(html, 'h1&&Text'), + vod_pic: this.pdfh(html, '[property$=image]&&content'), + vod_content: this.pdfh(html, '[property$=description]&&content'), + vod_actor: this.pdfh(html, '[property$=author]&&content') + }; + let id = this.input.match(/\/(\d+)(\/|\.html)/)?.[1]; + if (id) { + let baseUrl = `${this.host}/e/extend/bookpage/pages.php?id=${id}&dz=asc&pageNum=`; + let firstPage = JSON.parse(await request(baseUrl + '0')); + let chapters = firstPage.list || []; + if (firstPage.totalPage > 0) { + let reqs = []; + for (let i = 1; i <= firstPage.totalPage; i++) reqs.push(request(baseUrl + i)); + let res = await Promise.all(reqs); + res.forEach(r => { chapters = chapters.concat(JSON.parse(r).list || []) }); + } + VOD.vod_play_from = '努努书坊'; + VOD.vod_play_url = chapters.map(c => { + let url = c.pic || c.url; + return c.title + '$' + (url.startsWith('http') ? url : `${this.host}${url}`); + }).join('#'); + } + return VOD; + }, + + 搜索: async function () { + let [url, params] = this.input.split('?'); + let html = await post(url, { body: params }); + let list = []; + if (!html.includes('没有搜索到')) { + (this.pdfa(html, '.search-wrap-first') || []).forEach(item => { + let url = this.pd(item, 'a&&href'); + if (url) list.push({ + title: this.pdfh(item, 'h3&&Text').replace('小说', ''), + url: url.startsWith('http') ? url : `${this.host}${url}`, + pic_url: this.pd(item, 'img&&src'), + content: this.pdfh(item, 'p&&Text') + }); + }); + } + return setResult(list); + }, + + lazy: async function () { + let { input, pdfh } = this; + let html = await request(input); + let content = pdfh(html, '#text&&Html') || ''; + if (content) { + content = content + .replace(/]*?>.*?<\/script>/gs, '') + .replace(/<\/p>/g, '\n\n') + .replace(//gi, '\n') + .replace(/<[^>]+>/g, '') + .replace(/ /g, ' ') + .replace(/\n\s*\n/g, '\n\n') + .trim(); + } + return { + parse: 0, + url: `novel://${JSON.stringify({ title: pdfh(html, 'h1&&Text') || '', content })}`, + js: '' + }; + } +}; \ No newline at end of file From ba9255e28306b965d71cf81caa7cbf5b37f14d24 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 10:05:17 +0800 Subject: [PATCH 30/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=96=87=E4=BB=B6=EF=BC=9A=E4=BF=AE=E6=94=B9JSON=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9B=B8=E5=85=B3=E6=96=87=E4=BB=B6=EF=BC=8C=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E8=85=BE=E8=AE=AF=E8=A7=86=E9=A2=91=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=85=BE=E8=AE=AF=E5=8A=A8=E6=BC=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "jx/JSON\345\220\210\351\233\206.js" | 2 +- jx/json1.js | 2 +- ...\347\225\205\345\220\254[\345\220\254].js" | 101 ++++++++++++++++++ ...\347\237\255\345\211\247[\347\237\255].js" | 0 4 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 "spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" rename "spider/js/\347\225\252\350\214\204\347\237\255\345\211\247.js" => "spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" (100%) diff --git "a/jx/JSON\345\220\210\351\233\206.js" "b/jx/JSON\345\220\210\351\233\206.js" index b0f4703d..1965a65e 100644 --- "a/jx/JSON\345\220\210\351\233\206.js" +++ "b/jx/JSON\345\220\210\351\233\206.js" @@ -64,7 +64,7 @@ async function lazy(input, params) { * 包含多个备用解析接口,提高解析成功率 */ let parse_list = [ - "https://zy.qiaoji8.com/gouzi.php?url=", // 主要解析接口 + "https://kalbim.xatut.top/kalbim2025/781718/play/video_player.php?url=", // 主要解析接口 "http://1.94.221.189:88/algorithm.php?url=" // 备用解析接口 ] diff --git a/jx/json1.js b/jx/json1.js index a588aa42..7a0886d5 100644 --- a/jx/json1.js +++ b/jx/json1.js @@ -82,7 +82,7 @@ async function lazy(input, params) { let timeout = 8000; // 设置请求超时时间为8秒 // 调用第三方解析API获取视频直链 - let obj = await requestJson('https://cdnsrc.cdnapi.top/json/?url=' + input, {headers, timeout}); + let obj = await requestJson('https://kalbim.xatut.top/kalbim2025/781718/play/video_player.php?url=' + input, {headers, timeout}); return obj.url // 返回解析后的视频播放链接 } diff --git "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" new file mode 100644 index 00000000..b52c650c --- /dev/null +++ "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" @@ -0,0 +1,101 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 0, + title: '番茄听书', + author: 'EylinSir', + '类型': '听书', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '听书', + author: 'EylinSir', + title: '番茄听书', + host: 'https://qkfqapi.vv9v.cn', + url: '', + searchUrl: '/api/search?key=**&tab_type=2&offset=((fypage-1)*10)', + detailUrl: '/api/detail?book_id=fyid', + headers: {'User-Agent': 'UC_UA'}, + searchable: 1, + quickSearch: 0, + filterable: 0, + double: true, + play_parse: true, + limit: 12, + + action: async function (action, value) { + if (action === 'only_search') { + return '此源为纯搜索源,你直接全局搜索这个源或者使用此页面的源内搜索就好了'; + } + }, + + 推荐: async function () { + return [{ + vod_id: 'only_search', + vod_name: '纯搜索源哦!', + vod_tag: 'action', + vod_pic: this.publicUrl + '/images/icon_cookie/搜索.jpg' + }]; + }, + + 一级: async function () { + return []; + }, + + 二级: async function () { + let detailApi = `${this.host}/api/detail?book_id=${this.orId}`; + let detailJson = await request(detailApi); + let detailData = JSON.parse(detailJson); + let data = detailData.data.data; + let chaptersApi = `${this.host}/api/book?book_id=${this.orId}`; + let chaptersJson = await request(chaptersApi); + let chaptersData = JSON.parse(chaptersJson); + let bookData = chaptersData.data.data; + let list = bookData.chapterListWithVolume?.flat() || bookData.chapterList || []; + let urls = list.map(it => it.title + '$' + it.itemId + '@' + it.title).join('#'); + return { + vod_id: this.orId, + vod_name: data.book_name, + type_name: data.category, + vod_pic: data.thumb_url || data.expand_thumb_url, + vod_content: data.abstract || data.book_abstract_v2, + vod_remarks: data.sub_info, + vod_director: data.author, + vod_play_from: '番茄听书', + vod_play_url: urls + }; + }, + + 搜索: async function () { + let {input, MY_PAGE} = this; + let html = await request(input); + let json = JSON.parse(html); + let data = json.data.search_tabs[4].data; + let d = []; + for (let it of data.filter(i => i.book_data)) { + let book = it.book_data[0]; + d.push({ + title: book.book_name, + url: book.book_id, + desc: book.author, + content: book.book_abstract || book.abstract, + pic_url: book.thumb_url + }); + } + return setResult(d); + }, + + lazy: async function () { + let {input} = this; + let parts = input.split('@'); + let itemId = parts[0]; + let toneId = '1'; + let content_url = `${this.host}/api/content?item_id=${itemId}&tab=听书&tone_id=${toneId}`; + let jsonStr = await request(content_url); + let data = JSON.parse(jsonStr); + return {parse: 0, url: data.data.content}; + } +} \ No newline at end of file diff --git "a/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247.js" "b/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" similarity index 100% rename from "spider/js/\347\225\252\350\214\204\347\237\255\345\211\247.js" rename to "spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" From df5ecacacfdb7f344c1e9fcb659852f4002b294e Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 10:21:43 +0800 Subject: [PATCH 31/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=85=BE=E8=AE=AF?= =?UTF-8?q?=E8=A7=86=E9=A2=91[=E8=A7=86].js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...52\350\214\204\347\225\205\345\220\254[\345\220\254].js" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" index b52c650c..a1f2929f 100644 --- "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" +++ "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" @@ -3,7 +3,7 @@ searchable: 1, filterable: 0, quickSearch: 0, - title: '番茄听书', + title: '番茄畅听', author: 'EylinSir', '类型': '听书', lang: 'ds' @@ -13,7 +13,7 @@ var rule = { 类型: '听书', author: 'EylinSir', - title: '番茄听书', + title: '番茄畅听', host: 'https://qkfqapi.vv9v.cn', url: '', searchUrl: '/api/search?key=**&tab_type=2&offset=((fypage-1)*10)', @@ -64,7 +64,7 @@ var rule = { vod_content: data.abstract || data.book_abstract_v2, vod_remarks: data.sub_info, vod_director: data.author, - vod_play_from: '番茄听书', + vod_play_from: '番茄畅听', vod_play_url: urls }; }, From 5ad29727719972c9f81d8385901ddad3e85f2b11 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 10:26:09 +0800 Subject: [PATCH 32/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B9=A6=E6=BA=90?= =?UTF-8?q?=E9=85=8D=E7=BD=AE[=E7=AE=A1].js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\207\347\217\215\345\274\202\345\205\275[\345\256\230].js" | 4 ++++ 1 file changed, 4 insertions(+) diff --git "a/spider/js/\345\245\207\347\217\215\345\274\202\345\205\275[\345\256\230].js" "b/spider/js/\345\245\207\347\217\215\345\274\202\345\205\275[\345\256\230].js" index e82ac317..1ac29a6a 100644 --- "a/spider/js/\345\245\207\347\217\215\345\274\202\345\205\275[\345\256\230].js" +++ "b/spider/js/\345\245\207\347\217\215\345\274\202\345\205\275[\345\256\230].js" @@ -195,4 +195,8 @@ var rule = { }); return setResult(d); }, + lazy: async function () { + let {input} = this; + return {jx: 1, url: input} + } } From 9b3fc0bd6a5b9e38be5e144ae4f4eb18c5124350 Mon Sep 17 00:00:00 2001 From: Taois Date: Sat, 17 Jan 2026 17:01:21 +0800 Subject: [PATCH 33/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=862=E4=B8=AA?= =?UTF-8?q?=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...345\220\210\347\237\255\345\211\247[B].js" | 2 +- ...\344\271\246\345\235\212[\344\271\246].js" | 136 ++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 "spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" diff --git "a/spider/catvod/\350\223\235\350\216\223\350\201\232\345\220\210\347\237\255\345\211\247[B].js" "b/spider/catvod/\350\223\235\350\216\223\350\201\232\345\220\210\347\237\255\345\211\247[B].js" index 3b24d738..a699e4e1 100644 --- "a/spider/catvod/\350\223\235\350\216\223\350\201\232\345\220\210\347\237\255\345\211\247[B].js" +++ "b/spider/catvod/\350\223\235\350\216\223\350\201\232\345\220\210\347\237\255\345\211\247[B].js" @@ -8,4 +8,4 @@ }) */ -435F35785E45BA969DB95FC07396BBF327C50F94B452155A10B2127EB2743F686695A42CC071322F2A3F2D1F5DF8371791ED1331D3FC196192B1F5779953C4F0A74B825A27808280AF58BCEA6F33B6E1ADAD9A4FEA22075DE973CA16897BDFEE04A404065A3A4A9DF5598F7AD6F7312B612AF89D455139A6E96EE884F1D8D0404461A7D04472C01F875989C600C5C9B312189C7E05A8D06DE4EFC9C90E9626A577255A1BA848653FC669B7AEBBB00F15779981DF268A9FB202B853C63846F9220895F15EAA14568EBCEE1BC2CE35FF12BBC093E81BC02C4B57C6141ADC72B847C36F28028FF2BCD60D3AA72F6795DECC1A76CB2FF432D4DD66B253EF88909FC10E1FBFF1E7FD00ECDDA622B307053DA10648F23A133ED170B473B3DFE288C0219232673E5F11538B54534E9ED45A296E064C3FBBB1FA78DBAD5B7C42B2C286502F73421F3F448DC33E402961487AE257935734D0E20A2CB8037B47F2305DCDC5CB61AB7433D63150AC02AC258753EFED9E078291139039A81DD9E4EFD846D881724AE1A51228CD2D9E9D6896A63FF00479B9EF00BBC912F38FC624364BE0A1EE50BAECA4BA62D36D460EB0B70E4706EB787C62BF92D5B24629918C85EB2F0F914E58CD6759D248008B7388192A731530CC6E5CCBFA6B2C183114F6B099D7843510E012C2F7E09FDBA63EBF14AF321B293282997D1FB2B2199D350ABB235C7D4D4C40FE29993F5CE496AD45A26DBCB47527CCCCCC993BD007D29228BE3D813AD2B133390A39586B974FFFC524A9BFC96F68F9F295CB88A795AD7AD149E8139BE057244B9C2EF569AA1515845D22DE3654BF6B6149AAEDACCB9AFAA0B08FFA8B4104D3A2237FDBF6AAC3A1276C577C37113F3F411A8F6DEB33C2AD78341E9E9DD342EAD3FDD9D5546AF9381E50890249AD2E699F4E974D8808F8858E9B441373032693DE29ED770A0B9A35788A7C37E73922A0757471BEF52B8C0FEDADA03BE09A2DE1D222B5A2E20F0E56CF834BE8C7057F539D73728DBBBB6D06C79583CD86BB80B370A8EB643112C8234CE533FA48408B3BAA71DA651E566CAAF893F51FFF2F278041CA7EE421A03E96178BA38D585B168B4DC1FBBB4DBC855C425F74BA510A6E150175881E51ECD535EDC6B2C7C817CD5934C26A3486ACDB6C9E685D03B552DDD2D8D6D55903FF892B68C39097F05F422C27032D7CEADE1142C13C778291061E4F6F933B4795AA6DDAF057D5F4209AFEC7043F6F13C4B447BE11A7188BC439DF94D7F409BD7FDCBB726E213E02E78212620FD11599686CAF57D191B822BF6A2C3E4D387A3CAE2CE8F415DA13D83809908A9C9EEDBD797F8A6A3E0DFCDEFEE108B54E0155DEFF67291E2A850332634B28A28A213B5F4BA18B5F8AA5F0DD11558F32FDD9E78D15F67B04B91894EA8EB4F6506D60506C48B638ADF3CFB651590EE5AE5D869DA166CD23B634AF9A19AF1E5B70935CF0508EBA0D8F7A0D2B8321F91A0DAF61B708743A6EB7522289561273504A2A24A67F4651DB0DCBD44CBB4A62B9648FB814BF7C6E08671C03C7E0D2B56AED7E04332DDBD804559236022A9A4B0AF9CB04DB49D43B590E50943E248F86DE7F43F3E865022D842AB51BC9B9ECA8E47DD8DAA0786F161C5B5EF3E8C41A809AEA96F6B185BDE4F8A41306BA471740E5A38F6DD320F612A1AC3F10A485485124952139A26D1B30E5C3CAEAFB462927D28404FF79BBF0FED9C0BFA41708900E89E36FF8BB460C3BE6D94EF67626126A6F1449FBBC136E67FC3239E5F3793FC9E235A441C7CD3DAC7CECB1CBD4080F12C4C975F053045DC2B333BCE3ED7880A8C604718BAB96C339C9273C2BE62663833A99178882E6BC0125ED14B99A0E55535C65011BBA82EF1D5750BCED03CD31A2EFC249575011F387529639EB74B70F888850A50FE9477684F9A4E81B780CBC943315A303C12F65565DE3B060E66C733E355C7907DDC8401EDF2075B0EAAA4BE8EB9755DD92D3F3282DEDC7CC2771E256C7B1FC8434F2737D4C9C7A55072E36B8D9C07530E5FFBC2D70E643F0D3172D5BDAABF92B21DE2AF93966AE9D88EA917939B96D0A55351FD08BE8A07102196D87AEA586652BC53DBBC9952067D8E9E88AE6D12B772FF10057EB2BE32F2020B0E63AF8AD992F4696141353568FF720E3901980B27F32B24B2DE09219FBF0FC3B9E0376F5026558D5752DFCC73894B4261AA83B0A4EFB890F7215B50DAC1496BF67F1AEEEA31B3C8590E5DC390311C920E5472211FFE620000C306339A71F19A396B9F1589BBE9249E2A7FEEB1C56B42B89806AE62ADB41BD1AB93672DF5B426B447984C6FD5D82B9AC47AE78E2E1B02CEEA327DBB8F4D25258F0A53480FF68C788F133F02D923CFF658DF19D70C5D5E2E90FF659E1A5C4AD87EC5A93910F883FF77998D036EB5ADD91A6F56A78ACFEFD564E606AD2C93AF20A65AC03A0FD20C97BFE905950B22C028314F52F671CD0B6A268703EC909997B70372408C8A595C8DB35972193A76D5A39C1DD190955099DE507DB1A0AEAD1D78104F551F2A5AB25D4C53A1A5858EB2D08017909C4818AE75EEB8FAD7DF222415F76FDDEEA46AB882D626C23BB19080950D1FBCC8326CEA8249F13C669BE3A19754F8FEBC08EB0C4EBAC03DB1E54268276FD8D260E6532A58E41CFBB4311A48DB5459A2CCC2D27AE527144394371540A0150590E9EBC82325B42E403E7E857463E5757952B856B91DC642F4E43322BF0EB882A8F6EFF306B4004F3C183E6D4E9A0E7902FE1EC779CB0A7760720E036BBDFE765B2FEA463F262D87DFA5ECD4C38093F4993FF57AC74D11224EA30584301851EA36A4B86CDF186C96111E3449E69F9426DDA9AA6C29E409B4CA7F8DB95CF4BC202736D3AC884B00760CEDCBED1210A2EA017FAE4AF4AC082AC1441ACA99692222D0D37751D4767AAE64BE13B4C774FC27628E018AEF407D1AE64F03F91127F1CB924E2E1EAE89BB1D7412C26C629203F3ADCBA9F03BD213AD4D583EAE1C88C20D80149386C566936E0916567774B1276D0DA8880BAADB28C60C99279002F795819F3D8E2C58A58200ECD94761960CFD1A0CA735D67779341890F7888D5D0D3EAF5862A57998D0C6BA865AC2FC671885D84516297D03EAA021920AF521D448D8E9EE71B7F840D8F0C93218EE0B5FE07BADE0BD9EC6D1F12E22C2598E07B060FADEA688B1A5534F051C77660FE4FF00F79EC9881B0BFCF13FAFCB6E18004188FCF8B8A955CE0BB3C9368D5545751DC24853D2CA9F8AF798D11FD9574FDCF3AC7A888ACEF079A7C28F875177B3151CAF7CB6E84238A901077945678ABD363AA1572736ABED0E056029E754BE2D0333D90658AEE3F797B1C054D026ED0D1E055034C7A56655A08CEBC556FBF6E09B36F0440148195CDDD775E02245891B2011E38AC3B89939D88B5C6A12EDA6C2124320718964E603BF4A5032F63C112955BE80EF162F0C81DD0580066291A92581545432A239B6670CBF6DF1DB42341605353CA5C08D88591B0B065B666C59BDCE627ECD5D51DA5C2E92C54CA247542F99E3A6D49825C8FA3688AE5091E2EACF22AE8FA5A4CD65631D1B6CC4AD98B8C89C90A8D0910D30B656465CDD5DF4B08710BB916A2AA87E33ED1CE9A383C19369DBD152C46C2A6FF075173138565316F0A60B4DD93360FC07396BBF327C50F94B452155A10B213E8F78EFE0C9ED08F588B02091B4B69EBAFC8E5FCEE4E62FA6DCE39CA1D6C924F0B4332A7CCC6A0ABD1A0F0B67CF4DB1609C13BAF685A8C9353A2EAC2C4D3F7257E9152B5E289D17BB5B73959A49F877BF7F80C76F7B86675CB1DDB21404FA79EA28B61574F456257300302421FC36286D56342E1351FA3A158764EE162CCB97543468558BACAE631282DE11B78B563993ED941ED3451E9C0C2A3A4D39F61D87CA012885DCCCB0BD17CA28186B8C9F9FA3DB738E12E355C3208E337C505CFCDFEE74331EBE36B7A90DF91AF028441A51D2198992F969E8C3E9DEF8ADF16E01339A2D701B4B8A89AAABA1CF26FA61F00B8C305EE63FDB68B40FBC3BE227E9ADD6E64D2E784F2B44EC6C655479919A11793E99F5FDF45945797E786D619935CEE9AF4BB059F69527A45C196BB89AB35C6EBCE7507C092679F2BA7D0841C6764DF494CCB8C707E245C8F10D48E67F1CAC8B047F03D921C35FDF481AD46B78B87C4BFD7895D3A7FF9DE1C29EE2C573C5FF628A28458AD7BBF5FF72CEB83153270C50C22A1CABE2E619CC68FB784030FC84EBBF12C207606751AE0C707B1927F6BD42640FB540F099816265739C43CE0E04E03B0A0DB3094474BE690439F0772A73E3BAAB8B40484ACF326918C0FA6A3CC22F39342FEDBD6BD54CD43646F67F7F3AFD5BC717FBB4F22CE891411C278FBAD56A57A64A1863FFB10B163643317B21D14854F170905CE2B0894DBCD6950130D80C047E379EA5D982EE5363F9D2A6457A3815275889F1F00BBAFC5265D1B0887FC83E1D24722BE878D5DA2D693AE0FF6CD2B7F49E4CC0EBA132A74BAABCF9C66242AF0143A01F2EA6B4163E9196015D10197C75196581E5F3D28C11CE7AE02B8361FDC6CD13643A5AFC0BB21351910DE2CA47E33BA5C0972A666B6CCE1B9C62DAA8178F0942C96A4EA7B5E30FD87C11180929137E5AA496F275F527DFB02063F37D6C29CAB881BD4E5AE9886FB9842B86E8DAA9176EE9C2448A80815C6658E4AFB2798E348324AE2E9F27A874AB05190350B2D445DDFBA4A5AEB1410FEF3C09673C986D741ADC2781306F2930B1CBA604B3863CE19BF3FD78FE3EACE85F7355BED0B41AB740407E919AB98B062DC824A52E72F8FD627B49930D1C818B5D298CBD2F24290DC65E14A683B100092A2A3BC250D2AF06983C79B7D467C3AD941229E9D89C457761C061228F88776ECC2C93D53D1697A1FB1EEAA76AC1BD3AF43FDCED744D9CB89E8A4C342234C4B66F33928D2DD2965F4CB1FB7D7A1524F6755BDFCFD8FDFCA8FCE99C67C7828CE650654CDF283314E49962A28E1F8A7D654FB9EC3B8CB997A1BD08E7FB34C44B98BEEED7B79588B4C92E2ECA0B4F72D73BC46113A6A6E3E17E07AAD79E7585D793E5CBF7D829E626C71A5C91611C0036BECFDCB2E9C15B0F52178F5A31D59548DDF0BA0F3A6132A8D8E469DD32E43779B8AD10170399CC64EBCF6B04E44D6344406807781D00ACE8933D4154BAA16FBFCDA5D78C94C55B0F52178F5A31D59548DDF0BA0F3A61E9590F8712727B0D463BABD0F964CE89BA3830E0A7794EE34160B704E43DD174D2AF06983C79B7D467C3AD941229E9D88B247251C5DB9248713F4CDCFD778851796140B75F704D95B3BFD1DB59A79A7AFE9196A205AD4B2E5031929394417776C3994DFEA258A0A2860C0F2737B2E0C10897D32AEC1EB91BE453987BFB0D96AD0FC0C44D60350AFB7999DE88624185E923276034DC7796253D4560A0F841DFDB016BD3CDD13D6561CE0A69E415CD30CEBBA9106D82F166A6D3E8FAFE3B3B1F7E3A12C32DE46CDC9F3B761CB440FCC3365B0F52178F5A31D59548DDF0BA0F3A61EE68A987833C77097E538B19B926CDFAA2EF4663EA8C7379A5BF67FCB84CDCAE5B0F52178F5A31D59548DDF0BA0F3A61FA99BB5DCF1AF52BDA8A3F2ADEF75FA67C1B0A68B253ED0151563FF3E9ED84B818BD8A65ADC13D9021E3F7DFFA80B11C31B4DAD3EAA868FFB3B8A3F728C222BDA7DBE5ACD3E4E7547C51FC3C5D1F52D950D5757C3C87424C73B63AFBC4C6AC50106F71F9BCB94E5DD2E7590F915EEBF54ABD7DFE15B25A944931B8A48D335677F87F87734A730E8F90CE07DE2EFE6D7364F10DD581FC787D1B4BCBBC70FFE0EEA85984CE65E8EEE415BA94FDA1CC76565B0F52178F5A31D59548DDF0BA0F3A61C50E253EE3FAD89BE6152298B97138219BD7E8E76ADD1AE54887575B62956805CDB759037797E2E265C7591D35680B23F32CFF71D04ABC967827DBD20CC6AB324ABD7DFE15B25A944931B8A48D335677C317E3E5A8F0A31EC1E20336EBCDF1E07A3084ABD06F2F799616BAA890461B111D5E409BE3720F51CE50674C5CE75F649ABB9892EBC26A3B4676945AB51325521B25805656A7F2C5C1F4C6763F52DCD75B0F52178F5A31D59548DDF0BA0F3A61F6523210C73BE3747CB103E43AECFF646852CFA6ED371B71EB48C7639EBFE67B870A05637CEF0A50AA603056837F1438E56FF31DBABE17785F4443EAB6491F355BB58B31A3538ED0E79EC3752CC1E4845B0F52178F5A31D59548DDF0BA0F3A61851B028CC7B792DD33BAC70AF19D92C0078A5F6465DADBF7A4B77CDAC8B435CD82FFC7AD55467603E162F5F023C245607291A6F92798A2F10DEA3BC2C4AE7F67E62AA9F07E966C75AC39EB92C2D6804D73A66CDAF814D9C3951EF3EAAFB37CF80DB60ED2FEA32964A78D91D26C505813F28C0DDD34A7AC1BF58E0B800748F57F9CBEA21698A4E8B8DBACF81DFF89B81D668F097B50F3D2C53F6D5BB87BF26F332BB77DBB8FA16F618B2623503825A51FBE78F5A9FD23E4F66A4F98479F1A9ADCE09970542DADC30D964CB1A6E2BEF2EABAF0AC194EFBB7ACDC0CAFC58AD4C89152AF525B07851D7CA05B0F9944FCFB6EA4B86CDF186C96111E3449E69F9426DD11F08A32C3CE3BDFF37D6E3EAF2AEC8554E5F5CE52A5F92A9BBF9500687796E07B3DE3E23431A700F19B9907933147F8C1C3B2FE45CF2F3E244E6B870164173A924DEC731D64ADA7D6D100860356F092AFAE25926D89EAE216E9C94CC089F18899759E8396F5B5C1823C607B153AD1A0CB399B283C6B0FE993BA234C52CED8B4DA8BB5DDA77E8A59FEC85982182E8ED31E22070E06A125220DA1055112C0430CF0CCD04BB0C9793824D458A0AC53D3B7EFF4D3E7DE93D0D718D2035503A5099AA00B6D34D85F57DD96EF6522D370460D046FD36FA255D44A1F7C8E9DD49B57C7769A0947A5C2ED31055A465A5E8D3841BFC34E9DE955C79ECC5BD0EDAD29F427C32C4400D24E24F9EFE247D997C539011A472F70239B6FB2F895E993EB65470502CEC1E8F9FD6222E3E4FAACF6EDA0D8848F94DEA596BEEA61D3DAE7ED2713AC6C0134FC088050348C7B198801524603FFE17434BBD6A10A72E712EEC389C75ACC00E8AAA665C8418D1E014487C85C13496C31DFB6E6DE94817EAB42FB08AA7C02CEC1E8F9FD6222E3E4FAACF6EDA0D8D4887EE342362F29F64903BBE86753D8F918989C7F43EBB9497C7ED8C082881E321EE07FB62E7A4D84CDEE5CBFA9551C37E10CAEF20F2FEA31ABFA3824693197DE6E99048108EE9D76FABD77910181ACA7A274E12E59D44667438E40A679A04CF6BF6AB46440B65643CBD3F9C1FF0841BF3117CE42D12295D680B64976B9AFA359F0289F2CE66278B7CD7D6791F35249C36547BF8D6B3F8EF31AE86C5B9A1EA35F98FE01A31E08821058D69AEE1D3DA9DD80F93EFE8261CEF47DEF66072ADFA09B27DA881917A28E8253577A12AA662C07C1D3755E979744152E7C2708D437A77AC0AEED3B17104A27EF3E9E62C276BFDD80F93EFE8261CEF47DEF66072ADFA06D466652AA7470DD6A10D7487465F78F1B9208CB7B817A3F59C802350BBACE174A8FBC42E284F7F104802C0695E44FA1DAB2E67B6EAA637EA154F2A33A0D9D6613069C7A234146B28B6FCD7F1EA9F8F5B38922F55E96BB8A50732B5B8385BE3B8AF6FF3A4596FE7B6626E553A5EEE53DE7C1A07D2A16C221EB34C037AD1F7AEB461A1DC99712A45E829FCA1166857932D405BF384A7E8CA19CE4FF1630A3721BA1D7F58DE5300FD70AA6C91F4CBFB1B745254FB3A5D136C29B458FE41CAD9944FAFA513893A78D1FC9CC74C898E11E6CAC28F4AD3A85E574B45E338032B911896FD00E2581218A4A890F3F0C6F4BDB5DBC0A777C3FD91AFBDF870BDD9BD3A2DB10A4E3D08FF95F4D29845B4A6BED699149BD592DCFB06A21A5CE706E3C8B0AE2D9F6AF062B51B64E0A5FDED1D1A738B44918E6BFCF3ECB3A3761AAC73F6439D0C27B9D01CAE03D852BB8F3DEB1752924C6020A4A5DC38C78B932107660436C74333001E6B4A3E6FF9EAAD620029364B73A43ED596442381CAC1E74CBC4CCAAD5D596E5C1869C9A043E845DD48D07C57883879AAB0239B30E055EA80394CA2450D293D54FBFC411957EA632E8F1BDAD0C6F63B2ECD10118F9A5C56D463EF70E6BA481ABCFA29330C37283DF676101CD5FC8887379B3ADD6CD2C46D1FA6FAB4609CAE2921E1F4D6D21E0D13D0B689F9C702EAD429F0C89118ED0677E51A10727B8D0F7E24DF323CAE93434E552A4AB81FE31284D173AB286A2F0956E04C3956ECE1247E8ED0026C7A114E55CFCE24E2A506572CC77481EC38986C956F3A489B509851460D695815821E49B70AEA3A1237EF0CCD04BB0C9793824D458A0AC53D3B7EFF4D3E7DE93D0D718D2035503A5099A579BD3066E00A2AF59A770FE7E7259E6C66D53BCB6F62289C02346C3023196C94D5337834CE431DE4479FE150AB2828FE48AD42C771AD65DF2E3F4172C12ABD7B098B37D10BB88B63BC5E3CD49E85494BCF650C9A52C3A95F21E43415D231FB049A80138855720A4BAADCA8A5D570BBB2A25ED378722038D6FBE874F6B645DB36FB638A64566AE30B967EB1F36F958640E50E5BAA6CC7364DBEFAC85C3298280D553A879BAB18DA445B66A88041A8117398A0FD144653BEB6DCBB63F27F4AFCF5B518754369C26FE4396FA539A8DC17E07475E8F6EF88303C22C7CE7559F14A925644D7DE518D971617C7717437E34FAD9E69A5DD6EEA6AC1740029534F6D4C6ECF295DD2D61561CACAFDC9BF8858C29E73C54724E3B3EA4437845C03ABE8912E31B254CF5C383BD50C11B039DC6AE3C11C75B2383E21044F97EA6DBE2D02F80434887496EBD904EF99C10ECCFC7C0CA49692E89D41587B4604352C9B4C0717C48ED8631E608F8DDE85F56FBD9952F9934446856DCD03B2DAA5A26951E69B3AF470D76201CC7EAE77FEB4F8623CBD5C7E6D2A61D3FEF6EB2A43FA90AF9B62E0AEBBB9AD04845F8E803AA9F2C135E19B3DA0471DB8306F575733C38CE882A2D5A6EE9D6188673328FA453874085F35375710B2B16207910A7C6BFED365BF886841B8861B240626F45C7D542B4E74E202F46AC75CDB8D2A4153B8C7796D19E12736057EDB7581C513A415E4B4F7B156F9E4D0D2FE48200851E23CC3ED3295795AF84D13DF95F8F22214639D6AC48AE4176B8DB0E9926164C18EB7A152B14D1F2290D8E7D38D63759E30E2F8C4CF5B456F8B06DA8C3D768B22B864C89E1A7A3A1146AF37ADE19DA4A64B7C32D5790F287AFB88F3F110570373ABE8877D2847CBB96A84D6AB67FD90C25CF51AFA84EE0E4849C4A9BB0D66534DEDE64620BA7D6E20DD3E41E00B6798565DA910189DB3BE4BA9860894A53B9CDA0918F71684156CF631280BECD77883B477E387956D66E496218B8510894D07126785D43F486129A514435F5D3456E6DB4F10FF02BD0D3FAF705E32A432D27DE1453D495DB3EFDF1F25B0F52178F5A31D59548DDF0BA0F3A6182622ADEE0C2F9D5CC6EA248BC8F3E4A9BF0C019B433766DC8D63DB4DFD02C61C11B08C25FC30069FF545AE0E10A1379213D437DF597B5BC17050D28B3A4BF790B7BDC7458E45D508D1DE6D224407667E13DF33095E5985E3B2CA59EB613CE30249BFB072271DEDBF7E274DBE3B82D9CA652EDD0BA47C01D922ABF26A53B61350B1C1C4017398A092ED179929A5D6BD935F04948A5488AC8468967832A2C5D200035583584D8A7B7D7B8D98F1B330A7ACE2B6FA4E99157FBB988798D376D353B4E4E2670DFFD12B1850592AD7BB563D089385D155EA7B2CA31E0F60337C79500365AE9561B2046F54E3A4B2070965FB393DEFD5A50A882DA23D3F443D909EB58ADD9F12F5468A65286B1795F0925A3C01D729AB9256C860EF0505DC14F386376BBF588CD1A13AC0A95C3B0B7118C9013A8C1CB9B93EFC5A07BEBFDD2754DB6A2C0A089D17F028E78C40B172524C3835E1A44CDFE00EE3C48E87B61BC74F975E412A8AF1363162731C7FA5038C29F94B82B92C7731F824F910CF51D2006EAC09EC7F545886C93A65208E946CDF6FA6126559A0D4AF6FB48B7F754E31851111CC5B054A830F94B22856BBC9866812C49DFDC7F04322D90FBC0770751ADC155008DA28B2954209822AAE05AC882DE03BDA2E9D22CA0C974FFDCD176E373386E138DEE4A726F5403EDD3698CF8C4ECBC36D9418332A00F932CF66A809C9C4E89F47C5D2012A5CB3BD78A3714D202454533B7DA5C2E92C54CA247542F99E3A6D49825C8FA3688AE5091E2EACF22AE8FA5A4CDAE0B131F72A6B687544CE27280678CB4371AC190D6A13566C5B7BE108C07E04A10C26F008229CA00B89BE7FFD70E71E365457EBAD77AF9E2DD10401EAE6FC8D3213BA4BCB0BAD7986A94EB333F88940B640B7B0A6CDB2835C9A0EF3A5241774080DED89C9C31E4B3B7712D99F8DD1493A5AB7CDE8E493A08784794806F08383F3524DE856792FCACF108FC1C98B22BBF73C452D2EB5EC449D279785792274ED0119B67B5AA6A5158EE119DA181613F375203ED8E7D089B11059174BADADFB285D07148F7DE01B41AED70CD1AE270AACB25C43515DF9D8806E6B7EEB2AEBAC3AD70D9B8894B14F2EE058DBA9A30E5852A6D8EA122B04E5F03DDC6DE4ED8D3C5B593648CF930754FE985CEDE0BAC5AA107498C34808AC02AEC8033B95A40F7890ECD450BF13F9DCC6EA215EB0A167A98D726A726AF076CD83676EB8EA6EF6273AADC179CFFDE5BB79EAAD8FEAD7DFA0AAA3B78D887D3BACA022734C5CA856EF9DB6C041E85627DC21B93CBC6F6DE4533EE0C6A63D53ECA9AE9543D4C4A8F39D700288304DBB434EFCA3465E73047DDC138E59DC09F541C12F231CC3CC52FC454BFC489A4E0AC023596F306BEB658DB7481ED4C7665959A33E96476BBD0EB6E12B11E7E1C2F161F7FCFFEFA5C6C893C2849D994504FBEFAC908182AF541CA4BFFD9FC5879BF023F807420B455DFF15A3B3B3C31D98B046520A06D81117C4528903E2DFE431AFEBEA679B3D39A06265570490897D32AEC1EB91BE453987BFB0D96ADFD8199703DBD2F5EEB0C5B3EC37F79735B0F52178F5A31D59548DDF0BA0F3A617FA7DC55811EBE5BA6072440B2EFF51C47A53EA888AD57BF23793E671E6D495631BEF7704D01576F6ED6B1021A22F064CC69D2D157D182F57902B968C57986DCEA2605CC04271C14B269CAABDBC46585C645273D4F8D5A02A0940BEC17CC0A7D68DEFD5059CD66A112EF30F11929E95C80FEDA4E527B210AC6805F7CF1B5F327686AB7F210039B3E28B057D5E453F2A2BEF2881628216E0F3C5E6BBFC1A3D1B4A95B7088F598D07BA9AA2B05A751FE5A4514850F937B2139AE394BD7EDC4D4D98BCF8A573F2CBCB7E2CC288ECF7FE72B99A93CD708F380B443EC4AD28344C3E34F2FF1D7CA058C807521B1ACFF55175177AE2073EC3351734D8278AE66BFD8E68D39197FD11759CEEEE718D7CB0A20F0570DFE6C68F065829A7B7123D9F1E2E734BCFDE476CDD3C5108D6E801C821D9D9B11B6FBD79D4AA9CF4421BA0C6AF8CCB652786DC8D17C788E78EEE76738DA1199A898FF18C20F4D56E0BB9C6981A299D9F294F13A902A7736D7A8EF125B0BAAB2C06F1CE1F93BDA12ECE709FC7BC09D82ECC0BA28C95BF795B5580395CA01E7B916E4C63556BBCD7ADA11F6210278BAE02ECEC8E0F8497C882EC46E6BEB9D6F239D5593AC2C5ED9233E12545254FC78021594D825B8B0228296EA7D83C618A46617046C8139C5DFDF65571924186B7743769FCCAB5088003CD0E0D13A84A720D807A1C8275AF42A0F1E38CEBA9E89CFD066DD43143BA8CB2BDDCB70E0EA9C3D050DAC06B957C3FD42A92B17733A9669CC8825EA050F0897BFB8654CF73FD3103D8E2C58A58200ECD94761960CFD1A0CA735D67779341890F7888D5D0D3EAF58F7BF2D1CDC34837FB2DE4CE5917744F501A61CC88C8B2DDA88922AE71DA36A0F4435F5D3456E6DB4F10FF02BD0D3FAF71D813B7ACCE8E62EE036FEB59A615A85C48DFE1E60717DD1252497031EA5BA921A23E25B7759A6945327AADF2DD88214AE516BE150ED58AE2588E9E60094D7048FFE0F79EF021564D032E21446D125C719E9F92579157E46C49EFC03F2BBF46364D076BBCE9EB7C4D0E9817C58DD2441C865F7D47AB655C4E4A9D44F6F6F0DC1E928D9919BB223FF7DC2EED56A9EB6A9427629FB1F2ACA6BD8694D3915A5EBD8C6727D76F62E0ED33025CB0A96C13FB8358E4E4BFE720ED34AEB93CA3A2737D81586B6137F7449CB865BD9DCF5B007D59DC462B1F21A05374AD945E7892F084A670F0AEFFAB2230848108DAECFC19A5EB942B4505905296716388EEDF0AE0046CEA6F33B6E1ADAD9A4FEA22075DE973CFD3602175F2E21730C0A2A2EED60E08F326A35CCF51DA5C2859688F5E1F5DB16DB9188061D7279652BB5F2256BC1F538B026739142481952090A0034BA90190127C76D7CCAF353EF305B45C4E73E0A4B9B2D09D5BB07C43CA57844AF742957A2E20A6721F060A8B75A9FB5F72996637A507316C08D4C0A5DD0517832AE2CE4DE6A0D6EFEA98D1A2D10BF7A767F7EBFACE7F1730AB32D79EB96A8AF011B94CD69234B9846714C72ACA1D33D60647CC411DA5C2E92C54CA247542F99E3A6D49825C8FA3688AE5091E2EACF22AE8FA5A4CD48ECD595B525FB58E27E72490485BFDD6204C544522CA980EB41E8CED6912D75F57C23E0C19AA7A1A27E34B24E3279AEA289924F6E23640D7D2176D686C68539A1350FFEC701C2B233B14E09496C937EA6D457FCC1FB1FACF10C2B7F14FE1D2B2167F159E227FE8D85D1F305413086E863783E3A3D803312512FBBA240298A425B0F52178F5A31D59548DDF0BA0F3A617630D9B9740C169D8B4656DF6008E82664ABD2A15AF8006EB29485D159B6B9C36E982A4D6B76BF9EA05B300E2470C8F472F8FD627B49930D1C818B5D298CBD2F90E144C6B6F19F93E6AEEC0189B8946CF8C20613CD78024D3306C32BF6B74B61E05AFDD34FBDAF51C2F812C62DF2DA2FB787132026B705FC10D9760DFFB0DEB064CF1CEB156C8E1AE632F49906B1E1EA3475BB1BB36E9AD906CD8CF36559A2D8046FD36FA255D44A1F7C8E9DD49B57C7769A0947A5C2ED31055A465A5E8D3841BFC34E9DE955C79ECC5BD0EDAD29F427C32C4400D24E24F9EFE247D997C539019DA222E611379869AD081ECFDE5823C789AA97651399F8687572A5DF369E446C1C984FA7A917CECBA539AF7876F498F548374647CEA76FC7A51CE0DF25054BBF64D2BF3C4AE3D53E5969DEFFCC63D320848F94DEA596BEEA61D3DAE7ED2713AC63DAE331812F6BD3C6D75B795D96CBFF121AC3C56ED8DEB4719E47833B745267754A4C481C18DD50A161CCB03D8A067FBF93C4ACDAE0EFE39DFB12DD21CEA7C5C29441C7100F3C60878950202F95EA7EDD5367A3792298562FA882F34BB97C4976F74FF7A2E7715D2D03A633AAEF37B6027C66F78001BD6AEF522EF5EA68134C48CBC6A5AAFB7E6947F396A89DAC4857DED3EBA406908C3EE0A859A6573932409D841638D34583573978281343DF9C3070E023BC7653A1F9365FA620A0DA1B2EB4D366D0467EBC26DD04A76D07CA2FF57D285B0CEDF8FF40AE385DE1B5DE891AF68DDDB0AD8063D9C4EF8D416A6E378C60EC3367260CAD219209FD8589A6608D215E2CD27B56E4D2E94994233D78DCD479AACF3695B5EDAA77ED01260D7A5265DA5C2E92C54CA247542F99E3A6D49825C8FA3688AE5091E2EACF22AE8FA5A4CDAE0B131F72A6B687544CE27280678CB4371AC190D6A13566C5B7BE108C07E04A10C26F008229CA00B89BE7FFD70E71E365457EBAD77AF9E2DD10401EAE6FC8D3DD80F93EFE8261CEF47DEF66072ADFA08C4F39C61414EA2550ECE080444DF2A0213BA4BCB0BAD7986A94EB333F88940B640B7B0A6CDB2835C9A0EF3A524177408A046EE75B6739A7A2DCC6F3AD8E9EC7931518157EFABE2D82755B7CC4600A4EF8DEF8A95AA63D95B2B79067729A2322C2A7C8EED97FAB7A8E8735A57AB36154B3315E219681F77F05A8631D62FAFE55445F4447A0A91F1A23324C0C24E11A1D7E41D9758D5F016E4F5066371247CA28EF371D5708E10B714F4A38853D9D8E432A693AC2E157DB08FF30FB46B8B877A38A4297ED5649E4EFA63886F97BE49EE9B498C3322A9B946C06C5CE0E5CC9AB1FB95EDC53FD6E522BDE9057A2DDEC95942FFEA57A48827C8B74D2ABA4F065D1E6F48EBA8FD77CED033270409D9618F9086A56D4BAAA0E666F5D680DBD228EF82DCDFF67BC1A014E2244B99CEAC5CF3E83781BEEEA39C6291E6F16C692B6836541C4FF058620F17D8CDDDCEAA2F85D37255C1484BD3CD22EF2AB90D67067BCA6197036D99F18228A7DC2B6AF02FA4721357F95F736E121944711125C933C4F357814E6CC29C1918468D10B73B902CB05C196AA1BFF2EA2FFCC32E443EEE7F35853436B632DC8650E4C0D8BB8B99696FDC4EDD9FB35D048760FFAD4714247BE142E2891DD3ECFB11B511BB85ED29908FDF16E36BE1808C866067F87D9C9287AB88D6D440F547256240EBC9EC611391AC64DFCE9309C150B13A3970D58CA61B1831580FD6877AAF5AE5B9ABBEB8E624CEBBEBE7EDF3A2681A47EB0172347D42638B40CA4020BF1197919F7BB33E99F5FDF45945797E786D619935CEE90EB58D3B959BA8FD973BACAF2A32011B6A531C419C9F0A65E1E76607F0CAFD06D2BD87B0CC7D0B5E1B77F7C78665B5D325C43515DF9D8806E6B7EEB2AEBAC3AD70D9B8894B14F2EE058DBA9A30E5852A6317EBA7F3A8C28C5474BBEF6E4C71B24B17267AF12567255495AEFDAE3F3749E8336BFA373B9FD1C19D2F8F3955F5D830310F2043B718B4D57D689ACE1F41DD0BC91413973F1D3A4B173B02ACF433F863C55FCBC951BA1F770E25E8600C8131880FE9D37F7D00047EF6CDB9EBD9CFAEEC6DD840A89D6FA8D9DDFAF764255519A99CA040A869923FD43ABF31EEF7E9279EC27736687C42807DF5E4551AB551C05DAE114B8BA1A9F1A2DA26B7B1455B1E2B121D208F36A1F69109894F04580169A9D6793B0FD223CEED13A1FB69844E7DE8CEAF168E331D6D1830701F914A26656A800B525F777E2F96FBCA95A590FE8BB74D1AC98D9D158ECD57B03BFEF8CD823B7BA04100AFEE82B76CF2B9FBA1D1B06BAD069B4C4D08819B9F02417C4E72F00CAFB228C3806E81352733AEFC910DA48AA96705B2E05E68FCB314433D99AA0BC0D7DCC01E337840060B7B48939B816E2B68EE76AE01EC52257429211EF7BFFC68D3E8C4F4735D77661B1F85355990DDDE63233E2EBB17C11B8180EDA9A89C0482A5AD263A7097436D01742E1CE9986466E974CE29BACB0B4FD66D7BF6039B1ED9F294F13A902A7736D7A8EF125B0BAA944FC1A4C5CC3E0DB9A8481485D8528689CC0B8A9FDD4E7B570CE3B4FEC6246C97B4A3601BB42AC1378FBB68BD395534AF4E5C13FFE1207755A2895A9B8EB0774838529E781022A1C80EFB9A4ECA12D20AD938DE4CC808CD99ECC0F389F2E6CEB9B3A107733B86AE2D695912FC51D4E601511B05AA0B6E75F11938C8AD6C38371275F17A3D727417F102A4AD2B1F87D79DCE910FC2CD36C575F33143D1907F852B61FF138FFAD6AE8B58BCED4A1FDAB82A433AF2390CB56BA14CF55D0EC52DBCFDB55D49F4531E822C2B25A09F48A59C01CBE1E6C21188CF2DBE0AD7EC96C5735DD641CC5E591EF327B10568F07C2C35C28B783097178556424C4531BA4B602C439975C682ECD87C21E65AC8BEB0A5E978AD57EAEBBB1FD89D2A90CD2D17A1639B774CFB632AC8D754D6E5EE2D23F9471EA927A331815EEDCE538AF03B7DA13449692E89D41587B4604352C9B4C0717C79F19F146E372DD214F8451590DC5D2FB01C75FDA21747B15E7E98733C320D31FC123EF7DF9DC9CF9D22E96637EF378987598E649BA0FFC8C1816541B4C5CF8D5E06094ED40AF35AFFC4C92CCE7378D32487B1546CDCB27A53DB5257BE243B58559E383B34B922080268B98D91CC0982EC8B0AB75B3FC3E41577A712CA6D320320BCF3472C5EA86E94ED1BDC211A50252EDA4017C5EF9BE3811BE77A221B0E9A4A0C5F36AF4AB4F39AF51D575A3BF06BF2F9C2D17A98776A1394FFCC0DC7BB9ACC6C13A7F20A1403C9A57958DC53A0421F4E6ADB60CF94D46ED28094A96639F119807E43D844B84482070858B89B9D43089CD65AAF33E33EC7DE3F14DD59F309FB8C37B5446223ED392C9749FB62429E56FE066BCC427AF926C3E9F72DB65F1951ADBB5E7EF8051DF2785994D9D08744FB3893FA40AD05974777EF96FABA3BA6E99368DB582B51966E470E17621AA4B0C23EB7FB26B147BDB4776F15E3D187767634819F59BBBAC98BF65873C48B7C253DB025A4A7BA35DB3D172868CFF12EEE83E78120391A6F69C0605BD818EC7FD7FEAC8D57F20E856CC111587553AA0E67D06B0FF484DF6FF7ECEA4F665F7BF03C39BB3428ECB4EAFB8CF06B1F65DF4FE0C245BA22CD9C64B8A69572B7BE140A68746AC94DE3B5AA81160D326ACDED65958625B8D871CD4D52E9D71D6037B3DBE96BF0527FFFDF646D4347B9B6D633958CC23EB7FB26B147BDB4776F15E3D187766AF6B69824855FCA7782ED76717D96A74AB0680AC4387D390079F45049E67634557B39879DAE397B9119C03162BCA7AF9160845FA656C910A87D4E5A0DF8FFC20D5BA860AB6C2BBA04BA28E818D119A87D8556E35CABF6E2DFF1D75F4FEAF5EA12FA6AC19938058926C1E4D4AD3D1305288BC9DD983F5FDD839ABBE82B4FF21DBF9328B99C16A3C212D0532181A061A4263826C808ADC10DC8177852077C3D95737832884AB788888F3C9ABFBCAF9AD139BB3428ECB4EAFB8CF06B1F65DF4FE06DEAA2B49B3CE7A26101FE4B8F695F948177B2220888C07A889503F8875AF2859BC094266BCD7A6BB265B974AF7141B0D4D528B339D99F2C8A7BBB5D3CFB5630E1CF67D1E8B8586B6BF17EAEF0187950529F1496A9E4A01496C7EF9700804FEF6EB51C4A5C1BCC2921CA8D947F2724DB9F010F62F081828AC896028AE6B9FF2EE4A05EDFDAD29949A6416D93D973DA149F010F62F081828AC896028AE6B9FF2E43FE421CB812C6736ED449E05EA0AA7D39BB3428ECB4EAFB8CF06B1F65DF4FE0520A8316264FC2464483945B0B567E1CA16CAE87DC30A142EE104940FE2A1FFC06CD5E8F056262AB1C3290DD82ADA1E2BB102E6C96196299C036F93B0E9C9BCEDC1EDC7C415AC0D44BBDC5923294C473A3166DC2F3A0C338281A095FC9003318DDBA64189E9F39F65E203D59729FFE06B9B3A107733B86AE2D695912FC51D4E65CF6560695989E6307948549F7A404C537C8A0BA2A10BC084EC9C41E13C8CFC8C5589ED209CD1E02830DC6DCDF2957F90D72285B261D97AAAFFB29F3D3017B0AE31599C8361179CAACC680DDC60DAE5FF90E202A70A8860FE4BEB50404D32952EB1F6D1F4BA5A3AB489BE92A87C5BC9C659D8FCBFA632FAD238E874009F6F579B5AE3E6CA44F68104DCD6DF61869959AC6278154A07ED3CCBF1CFE879C7F59C0FE672F5065AE00668C41EA9A5FB8F4EE7F4D0D0949CBF5E8533862B7FD198582A1C8F247CC7CB780C54D658AEAE7365F5C31432438C46DB7E73994CE33B356182BD4859DFEA352845DDDD367EA48622DFD806D55C9F4E20F12B7EBF3F1BA8C5DF56493465EF98E516179F96A34B2DB0AE5A57729FE89EF4F55AB9DBB6C6C849ADF63B229FBBE3755952AF53975A5419CBDFC05728A042C281821E3B48676F718E3F1B8DE4062B86058CF16E12B3DF98E1D0363094C08A40AE9F0923242665674C4B693F0C789F0677B1FB1DF0321DDAA3BAA356C7C13F38D35B4E4FA53E6D37A19807E43D844B84482070858B89B9D434CD33EE6838BCEAD9E4725D585517082E589EEF6554FA5D57BF2C2B8B51A111E2680EC36750175BD9CBF09788D58E8F294B1B40D3340C0997722398FBEFF26BDE99368DB582B51966E470E17621AA4B0357C6C35A118DD8078374FB16D775625BD71502C091747F2837EB8233BA040675F56EE92C9C21F4FA3D566B0F58AEEB4BB4E91101A62F845CF8CFE867C5676FC589FCDA2C9E3C7B4449E2E2034EDB517D7506664B389CD225C0E5ADD4337A0BDD8A0349F2CD4D07C3B5B20A9C94E4A9EE39CEC37EDAF82480550BA7979D4A6596A022F5747C7767398E3DCEA56CEF37483A18EE239E82D6E949E27E39C5F8DD1BAD4E847E6FEA479120E5D4CE50C069FD0E118B176DF018C2E9560F8B8E7B545DAC8D8719E2C9E4F65E6290E694F86F2E4CE7AB3F52A354E142EEFE1F6DB9BD6552447933A5D328C2DDF4F75005EE359D54D1FAFCB3FFBC0E0E57492E7A29569357C6C35A118DD8078374FB16D7756257916BED14DC892F03CE6D89AAE35C5EA937538D53FB8B1B998DE89E2C3D0261FC022426E0EB711DCA89DD46D69369595E57D53C03E55C8F18725E07CFFE6442E5E32AA05B15F503B403059A9DD9651FD27D2B885DA5C522505E1F5FBB09C17FFD82BBFDCC430D63758DCDFD8C5247D644C3D559108EC85A32E9B724E2AC15143F02D7AF19FFBEFE70D75BACCC199752EE4CE7AB3F52A354E142EEFE1F6DB9BD66A888DAFBDF4ED7893361461F9E6F43BE155D81DD267940C1D2386488E0744089B6768CB0BCAA826AF28A33DF5B227903F12863ABD8702969DFE677244090B7B4E2063B7EF13AC6AA0E45C5AF22DD3216DE0B4B6B5532C75F2368A65C4482DDEB7D53137CE0A99A949618DCA0976EE96AB4FA47D42DF231CF3440CAA39FF7781AF4E26F76DAD47E2C296FB8A972F272137FE5328C16CE73F89CC149BB188545CFDC8923185FD01E1DEE40BF0A070AB5DEB8313DD2833211216BE343433DEA39FEEF18EC756A90DE38F63899AB05EF5881075859E3E6A91ACE9E0A408E0757FEEF04A74EE84B37B2E508C5C8FD67D8C6F6B8E3D6F1A6A955835314EE0B5289890FB910BD0C8AFE1A00306D862A9D3732C42C2D0EDE3FBA1443AF2F0B733D0C487E5D93B10B0C45217D6989CE274A83479CCA64E201E984BD5F4B111D689895A39E2583BEE800C9D0C1C4F74697CF6BFC20D723F7A221693D33AF007E4FF4C3967DE9AFAFBCD4A8D348E7D3C53D8B096BFE155D81DD267940C1D2386488E0744089B6768CB0BCAA826AF28A33DF5B227903F12863ABD8702969DFE677244090B7B9AC0812071D2F23539D5E0895219298A26E4F0C7F389341C9594E71A12B684EFC825072E503ECED440C1634BF31123CBB02BD3A06B1070452AFAEC843D0E54487E041DBBB23E56EDF37EFD7B133E88339C1BD4B4266271634AB43F61C17978553AA857E0173A4118001559480F5F9DC3B179944B79C9FA2491CAFE41C56D21DF9557A2658A0FD171C50495797D0ADB0DF13FF09F5FC2F4122F712DFE999A5F8119A52B444BCABCF8AAADF0D9C2F9A64E23A41F2720D95ECBE9FFBFCC0A5F593E2CAB7F0BC7F4A276777E19B7B4C09FF1589EE720F2132921A49A9A29698838F658E1B69E0F738F47A1EED119A916B538CC328FDE0E19FB158EE9D04ACE2286A6A716AC52E292FA20F57B5BF723717215F683698A3217B0880AA8766AF605D5BC58F6C9451549A1516E5E2CA37ECE1F9A289433DB28A8D06127C516335EC910B20EE3D9D8F9BE786D1CAA957D8A32A2955653F3CE8026F3D7AAFB85B738428732E45ED1A95CD900A3EB18603B5027766B9860894A53B9CDA0918F71684156CF637ACE4A690E6D52F687DB850D3BC970B7C20DA783D64AED8D98655B15807D03C77B3DE3E23431A700F19B9907933147F8F85A3BAD3537AA3CABE5D9720730A2E3B86D4D6FCA28F12BAA49D3BD93BDBF5F516F6C02F69E6064FDD5521333EFCB21AE59977C874F2C2B01DA361922FE6477CE5929FE39750363EA0A812451704DC646132035F5B13784E4169351DB8CC05285BAD843FB04097BFF444B1DAD1C56E82658297B26C51434569814B76882CFAECC9149BE5B15FA8CD666E5DF693C6ED665637A0C01B88753DCDD949DD4F4AF02D8C48CE7DC2F912400916BD4D8B921C806508E37843709568FF38810A68A6874F990860D7234811D2E8EF98951248F557F2375DD8E3172472876273C48CFB58FA65A4BAEDFA04AAEE677475D538192DEE941E51ABD98559633AEC8CF482236E94B0DDFDA785D4C730E61D330EEEA33364F7CF47EAC5D5560ABC35B95E76A45C1147E920968DCB6F912DFE114D6D40CF28051BB15D0ED44CD93BBB508A7D79DCF2F033461E32B0876A0EB74649492CE53F8A273635B09A4A46383CF5C7FDCF737CC010C03DC3C869F913CF0735E04C6941610E54B727056F19D7E92FB5ED9206B49DD67032DB094CB4B131082A1D1BE021EEB9E115D894301DE9C9BCB27B60F732FC5DA09AF7DCD7C5C4262C0E5EC37E97934526A32BFFBF3ACCEC4DBDE5B2D54320BB9275B196E1DC41EC5A7961C48D5283E8369F1FE554CDD06F4AF0D139EBEE665A0900F0453F6F976A07B01F6E4BF06E66656C7F2097F3C232EB4234A699F016499EFC1734D340E6655771D5A3400FF5B9108079986D4E18D261B110FAA41F7BA85485F95452A247B541EC2A206CF2593C9E618B892BFD5E4740502054CE2F4D14D0B7842D88B844AAE362A7BA4B4C5B95D1BEE3BF94A8A5F2171019E9E6467006479DF15F36DE3D32A2B113EC05FE09970542DADC30D964CB1A6E2BEF2EAC6EC558B2781E0A73642F24AC2EB76A82E7B7E67F5E7B09E42978833B205CD1C5D28861F0CDE688F8482E9B236B937984146610D081830806CCFAFA1FA0602A27388E6ED178B8EEBB71BDD62056E30609C84D16BF611CB6D456FC9EDB3D5EDEC6132B757DB24FFD46DD96C6762C2A6B6E548D5EFD5B510003DAFB191803F64D1641BC1D246464935C9641E6B27F73210589C98DEC2C76ACE1D0722D35E333AD903ED41398B57D253FCFD6BF0DFBC47F448339AD805D31D117EA82209E74F1CB840B7D9F5F5C55C735C1591085117A0E83F19804CBCE3D0BA73E5AE87B50804398899A34DD32E859C546BFF71B32DDBA1A1D2F1E58F75946D3F369FDC303E294A0926413A3C9BE63700CF89866B72B442FBF4FF9C5864D949FFECB4EB2A73315A3EA61E9D6E61041819AF06131C40B2D9097DA6DDA5C45ADD1DB5363B61448E48216D8A9C50FD1464353B8356A0EF5689BBEB4F475AD703E8B164237CD904D8096AA753DA37527F27154AFFA9C7859600C6B4764E01E5B2B4E7947A1433A2A0D8C9EB2CA0629646C3E24322728B1D41E2F3194FC14274A204C031353C09A71A2003BF18E5659FE623674BEB3BF766671905AB6251BEFFA1B4756C12DD43371696B62C07E31464AD8197844A6C5F0BDB5AB13937C6810896CAD5E606C3408FDB1A4F04E19AEE1C5BD68369EEFD0DEA288D33338E78D7F9783215D5A6042F64379923573D60C85012706E578569CF07B14E6A48E823C9CBA2D54452082BDC5EB5FD11BDD769C4DFCDB06955CAB1559F95EB5B0F52178F5A31D59548DDF0BA0F3A617E865FC8DFA8C90AC15ED1FFC7869D119E2BADCB0582A88447ABCE80973ADED9DEB2DFB6E9CCC63341F54C0583966797026BD11F61D5051CD526DAFECA49B06AEE6EF2CAB3393A22A4E095CAA967327F5E57EA09B31681F0A6C02C18A171C3ECB13937C6810896CAD5E606C3408FDB1AE7A7A7C9041588772C3789671A075C6E75DA896840452C98BD8754B7BEBDBBFD2C9457BDB274F6010C265A366C7A1D105B0F52178F5A31D59548DDF0BA0F3A61DD80F93EFE8261CEF47DEF66072ADFA0C5035AE2DA56D416D9BFDF8F82FCCE1E164AB97D42603A7A0719187406FD3216FC53101E213F9AC47327637241C978475AE512BAB58FFDC1B61B363D361C03DA2A7ADE6057A013DDEE663F903D5B25874ABD7DFE15B25A944931B8A48D335677E7DE8ADD1A3BDFB07E9B4C8A71F786DE5B0F52178F5A31D59548DDF0BA0F3A616C93BF1A92B7478876BD48267CE8EC1E5B0F52178F5A31D59548DDF0BA0F3A61CC137901241434AC46AAD19EDF470B3971331C29645F2E7C637DDC7EB28864354ABD7DFE15B25A944931B8A48D33567743C32FC557519ABC4C8C5C90F258A7F90897D32AEC1EB91BE453987BFB0D96ADE180E52CF4549D0752C27EF3E5ED492F3CFE1848B1019E4C80F376242A11765638B22524E619EE4005C4FE4C0D6571FA49692E89D41587B4604352C9B4C0717CF3DA6677831B83EC31BACC85D19F66BD498C34808AC02AEC8033B95A40F7890ECD450BF13F9DCC6EA215EB0A167A98D7411035971DF9F4FDA3DB14593DC3F9A27C474C9D5815A0FFB575D7779B9F295B351F40544A4C66C524961B3C3E7AF0C24D2E75ADFA99E4765985112CB45160C990DF84F86DB775A51C0C20EC935519727ABBF5B20C57306C768DFDB524987F4234C1A78416F176C1FC6ED2DE39575A079144EC82A0278020A4834972034A9EEE72F6795DECC1A76CB2FF432D4DD66B25A58933850E097D8BD741426BC67EF0B84153C8E0A557599FA5D44019A311763988A7C37E73922A0757471BEF52B8C0FE587B6B116070E137B7C3F444FBA96F8942588CA53E29954EC6A18F24D0AE3D50B33125E4FEA5B0F1973752CC1E0BB8156F3CA33EFFF18D377E83C0655D33C435895AFD46EEAA55EC0BE894E9567B47D7D2DE8A816EB20A431EC61B1AA311BE8F2B1C0E8135E3A422E7D3372AF62B79E2F1EF75954DC101F1BF2E87D106AEA2092C4B311A95C519012D27C5004BA1E09102A7F0F7DDA87844833D947F991E1561BE22B480A097570A57544216A50917ED3A77B2BBA3140B7EC3EE4A03031CDBDA0DDF90083D988475BBF4F76B109E83D313644E33B2E5B76B98D9D9838AAED6ADAAA8B9C747F48092B5C7BF97CE9B9E7F4FA0C5857076FA21470F1E2233C69D43EC7D1BD9FB1C541DB5C9148BD3D164647232C5F004BEEFB0BA3F1B00128A434B1815147BD00A61822348EB3E3FB1083EC7BDD459CAACD236016DF3B69CDD5561B30121FDF3F8D4FC0B09711ADD854BF42A2BC64329D4E0DC1E1AF326C81A6FB8EE83A4746731CFA14B885D1376AC92EC184D62697CBBCD79D4130FFA13B0E2AC8C5781490FD0A990FAFE6DCDE96C0D279AE47BEA96FED2C4BF8821CFB03FEED5498C34808AC02AEC8033B95A40F7890ECD450BF13F9DCC6EA215EB0A167A98D7FF49DB02A17E7977BEBF2FCCEB999D7FDD80F93EFE8261CEF47DEF66072ADFA0892F05AB9C52EF597BA187677A8C8F8B1A44CDFE00EE3C48E87B61BC74F975E43BAA356C7C13F38D35B4E4FA53E6D37A4910916848DAF5D8F3CC1662D330D1E8D2AF06983C79B7D467C3AD941229E9D8E2583BEE800C9D0C1C4F74697CF6BFC2F2C4DAE3B7CB2966A56D1DE064B0CE3FAF4E779C6E735887E27F6A31BA82C53E4ABD7DFE15B25A944931B8A48D33567709A1B3821FF0C4C61A08C634D48DD040A04031707A3E82175A95E6D68E4B424DBF1586B714E432F5654A760846B0DF596ED6905F4DFF281D9607AEC42AF8E3F2B8F339A0FF7C003EADD0F46D58D80D56228969748593DF6E05A1B6C03CC3E91BD72D8F820785B5A457B2BF44480E74A59A387A77E23C212A2EEA5189A3C565D3C737C11B24F26A0FBC84F2CD94EEC34CC4BE08034AD58EFE1535FD6F32A1EAB77B9C68D417D237A2EA62C0A170470A3133C3511C6D238D1FED5FFDFB745B78963177CEF8FE908D4B42D9326673B22576A1DF589D8A78921D1C2A8A89C6F4942F68FCECD4AA7B0DF998934B7EE5B6072536A468566A60572174C563F215DA9FA450D5757C3C87424C73B63AFBC4C6AC50106F71F9BCB94E5DD2E7590F915EEBF5EA0D81DB8CB15B9EF5A5C221C0AF2847945CF25F939FE9BA9311BF3CF89BB32142ADC618F8B5C37B678AD7D3D95AD6A220EEE3F696EF784CD6E0C2A6E5E46487D2AF06983C79B7D467C3AD941229E9D8BA4167D00D2B2F03E2A24DB16DEBF145124542D7F69C51864391AA980B17C7927D34476364808BC45A0C842A49A7AB7B1D7A1B62F36D79F1A6B8915F176D9FA8E162B662B9CD0FF9203AB4086902DE90EEB37E936F856657FB7A04B84507B692DD80F93EFE8261CEF47DEF66072ADFA07EE7969AE7683C92AADF892326662AAA6ABED20462DE540B6CF0A7D8F4DDE089AFC3F7B8FE713764C127E13859A80668A3A7263672D76B941900C1345BBE3448C9232D1858CEE18B956E46EA9FB7B16ED23C3D577E3B396689553316A161A822D7EE69FB365139BEFF4C17634D729B6EDB4FD3FB0572A7FAE7814459975A0726209B859875385DB62E5E84B45BDADEDCFFBDD2498226587AD0A97E0379B6FEC7BBA9106D82F166A6D3E8FAFE3B3B1F7E3A12C32DE46CDC9F3B761CB440FCC336B997A1BD08E7FB34C44B98BEEED7B7958EC14FB29ED98D953151E362F47260C2CD04BE2ED2D9CD563FBF5C070669743EFF3B168AEEDE001ABE4BB9D6230E86780814713C95889D42144740EE33D521ABF3682F499A5CC231E09CB5482E3EB3226551767B1DD7A899E1C47E616DBAC4729FE1AF9001A123F6A2187999144D6CF17A6B7C986B025BFB1086B5A505088CD61275F17A3D727417F102A4AD2B1F87D79DCE910FC2CD36C575F33143D1907F8530A4A04B3010F9E7D1DF18AC0AAA3B8176C539F0B9EDFB5C0AA1E7CE9F6618E52091CD504B163786BD94349A46B9F58F44AC6276F63C4CFEC6F45665043D7CA2CAEDCD037E43D7B09A547A9B5D2E6A7F666283055A9B5FA04E6A13A8F9F547FE1FC1F809A42DBB7059443C9FB1FBE910E97AFDB841285E1CCA2E9FE974CAF499297045C85D59467FEF392EDBCE5375B7563A923ABDE3F8E93430907BE71187605B0F52178F5A31D59548DDF0BA0F3A61DEAB8101ED96D01E176FA19ADBE613ADD62F17C8D560E8CF2EF0C1C533CBA86AE8F774A4CE3307C4F8065D100712D65FB997A1BD08E7FB34C44B98BEEED7B79550B1204EBC9BB0E030A12488E2F56ABA659326B5351DF401CBC66D55A1F2EBAE37561E7648C56DF095962B8683289E6FB02EBC4B7D30D718B8A4B85677DC618243E7D9F44C8EEE6F036C847C7CA21EA07AF3261856EBF2E6F02C0D3AD6F0C466001168D584F92E641D14308B07515FA67F85B46363E9EA8E795771AD9211F42AB520AAE83ED7A60A34BCCEC6B98EBB05D77BA7CEA2F8D5C69B9DEBA71DEC1018164AB97D42603A7A0719187406FD32169DF703A4136A53466C4EF680EF3B1C3FDD80F93EFE8261CEF47DEF66072ADFA01D156AB733D6965B33EFC0774B4E70B26E68D72DA7B7270F72890003CC526930FB318C02285D8D02E0402BB2211C40B235CE955BF175FC56276D400D15CBFC7E1B2023A8C3C3EE7C781BBB33CF7A256850AC6768F0D1F5CC8BA97DB6270D4BCFC9EB2CA0629646C3E24322728B1D41E27F5BB1D5B7F00F03E1C290B2883F165419914B95BCAC91FCE2F6D67C561F0F21C700E3C74FCC167FD790ED747253F13EB63CBE5FE6AE782BBE6165BD294CFD06944FC1A4C5CC3E0DB9A8481485D8528690D9FD59E32749CB68BC1CCEE6DC672CB2D9B9380698F04661E0A278DE308BB3A62C33A68F66ED09E95D7ED37EA51212C761FF39FF07CA1074E4EF94378D6E62DFE08468FD6B20B7DB0D368210F5F48C0943E4C35E89390AF250169D3CB0F2CA00AD7E738BFC7889C83804EB7685B3453BAA356C7C13F38D35B4E4FA53E6D37A9F62C5892688B3F6DA6C72C17D442F4A0BAE48F3E792CB1B210022B0719F4A130211BBA8E2F26F6C29F352B6063A0E31942D0CB0FFFEB58844CC0BBAA24F871359ADFDC741F537AD656F04659791C4961C1C8B10A1A1AAC92F8705BE1E544EB85B0F52178F5A31D59548DDF0BA0F3A613FE694CB63C78984437C15F82DE65D85DD74B5E0F7AB512BCECEF0AFB9F587468C722F2C94DBC7631BBDE2D3C85C9AF0F38284F4C50AFEFCA3B594E2A5A106D3EA06716A8E450B953AAE90CD83DFA63C5B0F52178F5A31D59548DDF0BA0F3A61D53E381CF1442E2748DC2AC2919D3C53B6B9D234B01046454C6F53AD92A243372AF030E83B497BA576DA6767AAB2428273DDEAC46653026CB5E9C641151702AE00E8174E841C88EE28F353C2604FA7B70FC0C44D60350AFB7999DE88624185E923276034DC7796253D4560A0F841DFDB016BD3CDD13D6561CE0A69E415CD30CEBBA9106D82F166A6D3E8FAFE3B3B1F7E3A12C32DE46CDC9F3B761CB440FCC3365B0F52178F5A31D59548DDF0BA0F3A610E3543CD4840ADA8B7896603E2783D39E928D9919BB223FF7DC2EED56A9EB6A924E91523DF0B71F56337F1C61E2D9D9120D48C6CA5594F713B704535183807880DB60ED2FEA32964A78D91D26C505813512DCE47F9C39BFA579529609120E762A7DBE5ACD3E4E7547C51FC3C5D1F52D9EDEE6DF859F96B4C3DB8C6385DA0A4FD5B0F52178F5A31D59548DDF0BA0F3A615D0F434D5B36C0201402A9550A730D3DB1F9A78D34ECFC7733AAC4033A4494977105CFEF8BDAA379F7CD88457C5DCCADCD95DCF427051F37A01A4824913869054ABD7DFE15B25A944931B8A48D335677D0B184973D766720CC921BD9D3AD7DA0124542D7F69C51864391AA980B17C7927D34476364808BC45A0C842A49A7AB7B4ABD7DFE15B25A944931B8A48D335677C317E3E5A8F0A31EC1E20336EBCDF1E07A3084ABD06F2F799616BAA890461B111D5E409BE3720F51CE50674C5CE75F64648B420BD31B9B71507A1E4A2ABEB6E250FF55DB3711AE9BF962E7BA41C8739ED3F1FB96C62347341AC1807F45DEBA1960100825F3142BC9CB23C5DE6D5CC5D478E9D2491C6C1C9A414E5D6175D5FA0E5B0F52178F5A31D59548DDF0BA0F3A6126F652A1C2E8594F22872DD443DC84E84441A36CA09AD779FF85E85181DA9DE8BC50398EFDE8C90487488002BE1105690CE3EC5C6632E98CAB4ED73AFD7FAFEC3CFE1848B1019E4C80F376242A117656EE383AF12A2A70F0C38E9D2298FDF98536E3B295652F30153A37428C4C49218C9F05240782EBD0B97AF4ACF8233FF366B520AAE83ED7A60A34BCCEC6B98EBB05D77BA7CEA2F8D5C69B9DEBA71DEC101818C17CC66C403E2C1C212035EEF9901F195CDDD775E02245891B2011E38AC3B8E7F5DB7A1EEE624B145AAA974A76D2D6DACB16F00DB95E55939EB81597017B0134446856DCD03B2DAA5A26951E69B3AF3C8D6641EA16EC1CD7AB03C4BB6B4A1D3265F59DB1591ED51E61DB5A5D1A2F87553EADA174C3540E2D9540D4EC66D04A80D00F46646D66B3A859B159D6A50D4B5A19B45AA6353DD06BF85606A78093743DE1513AC19E8F612180371AC979C2FB02EBA99FF4153DE80E589AE2442695EDFB0C312C53D166EC2AE1D8CAF351C149AD49829054A899C200C92EB6BA747CD1103209767A86A7032AB168C2DFC59C784140E825A57EFD37501B2D29BB397A2F45DEEA614FDEA1436CDCBB5D2627175F50F1D9B7DBD8DAF7F63D3979C20528E6EC12D51F057B0C5DFF73450CA1F0A24DDC54DDD2F3B9E32019C0A5AFBB831FF99C0E0458E86D8F42D25B9F881D631C6370D0D3E59F522F6656170AE14F9F8E6DAAB9C88DFE07A6F61FACAC3EEA42A392210F06AA6CB0356254D374C28452C62542C211FC4BC31B47E5882266AD153BD7AB2265DB85D57320BBF6D59C3BD29AC4B744EB2E7D627D1806DD47477E332615693AFF192BDDAE8B775F702EACC0FAC789F6487FF9A4253BF23CAB5F7DA582E62A096C0BFBFAE46800601113BE6D19B2935E022CA71446B64094F75EA08B440982CF95BDED70FDB019C97A1B39208473FB42515FA65673E3FE7F491A73F8C112178F0942C96A4EA7B5E30FD87C11180977491AF3721A13D83890A3ADE53D753D8DD104A536A2E182965645EE362837DD1AE5F727EB45348AC939204DAC4A68E126E71E33E592CD0BD4EBF2D8331A4BBBBCFDF824206EC00D213B42C85ABDD8DAB8BDCCF2EBCE33CC9C8D20DB219A7D7CE3B57E9ADF82F20CBF65F1713D2D8D8413229567ADCD6406C402E09CE512D7C2EA5805BFDB335751A2DCBA8A00E57FA88356272C378DEBC61830C677BBA90B47361F0B0C25BD974685501B1A9F65F712006417C43123F4A48034654A69865091B79DDC82844A17CD1007CAECBA47AE34C3C682B02F5A766FA34248F7988CC0D24AC68D8565FD52F468A43D2EE000EE4192EA47D306588E0C36A568EA7A0752BF2AAE151EF528ABC3AC39CF9B6AE7A5B5DC017FE207C6B033BE57E3F321B1EF0173C7577A73C475CAF3D792E9C47E6533C7F6C5F0CB06C7CBB52EB31405E70231824F7FC0F9F64EA32802F114CF8A6B27DBE6C260201DAB6278A8FA05452F2FB0E60B1B527936DBC64F83D2A4DB65E5209D02A3C1EE4EC8B86E26852F0106D38933E3D862CA185771DE79AC31EB8034C0CDF9EA0163DB4EED20344B99E1DA0D47801D9849760DEC4BFEA8B771C5E102C66564BAC5534C7D1A43D47A7A17C7325BE732D70177BA8D4FC6232D0D6E5598C01BB493054E8F288D30D0FFD54E1B22EA4336D8F6599164F75B1D20CFE7E477EB5AA83E427D5407FDAA25349981AE48D2D3BE8707BD6FABDB620E9CF031B88FCB74F8A9723C70A401584D939F99F44DB4EDE558C86E827C8FF63E55376903651147E33BA5C0972A666B6CCE1B9C62DAA84252A1E9F880CE89946E9439B6D4B60972CCFD3E5624236858DFB874E3F53557A30AB3FB6EA7243B9B1EFCEC35EA4617D8B42BA54408832AED90683E4E22758A915D0EBB5223982F805F955FC68C2EAFDE2DD99E13A8D9E37B531053E980D81E3CB5E995D67F44398FA853E179D953E21036260B8D514379AB95625B447A42502E2D8AFC990314B504BD4E3413321686ADEA7FFE5864F8683291744A79D8003C961E701BA8DE060AED2DE23FA32C8475C3AEEC0014CF5ECB401463E4A47F06C5EC63309F1F57A2F1699D00B75525722E8BF451297D27AEEAB76782385F1E0A95051D543B4807D417E19AD2F332FFAA57F6727B801AF8F0487CA111FFC07C81F96F911AD1E75916CE6D37EEE631A6A2D8D585346703B261917C7DCFA178E55F45ECCEF116246AAF05E4A6F0527AE4FBCCDABE4287F73FB46B05849D920ADC00E611A7BF6CC4A65F1FB371ED68862CE0964DD44E81AB64EEADC571EBBD5225BE78DFFC5B65EC3B62BB55493AA0FB8796B0EE28D884F8C0E6B2DD2327B5F62D6615A28F8E2393FA185A982C15F679439B99E981BFD99A66CAEAC46FFDF2A665AE537BE34DCD020DC6C994E7CF310A57F807E209AC156A16318E2DF9B9E7114602CBC749CF5D0DA747B22B176DCA1546B774DC2785FE38C1B182BF5438807EA41B8E31159967D4C926F50F359569F521BBF17A42DE6E749617458AC223F5DFECD40D384CB447381F945D16D38E55F329FB9FB06AAD61D1F57B8BE021897CB9D539ABA6C5453FF323B5D8B26D47FA061DBD6098256F5669DB566717C2457AADB8BC487A085B5DCB1A87C2C25D743EF44FB174B66B6675F14C77FDB9B28FBAD23BF3B0DB0991F1FA1BB343063A9E8A961D3D4E47CB4C41F1CE18C4097BB71A4193186B76694A4C1D67825D2FD826D1D00711B21E51F147883BC33C19ED427878ADBDAC3BC7F59BB0E0056BAAD24E35D9C523587C235EF7E399CBDDA77D10F05F7F1C9FD34957EEB30DB6BA17BCC7DE0983C89B9AC539394740355437537666A77413C0A1F2E4B2257D66BBF948B6C3D88095AA3A2E1B3EE4A0834132ECF15756C5F19AD45059AFF07B43C3B307083AF349A1CD2048D52E2E74A0715ED7074FF74066CA5274FD226D29E8F9A5BE22CD317772FD0AE65CF74A6F671C5064D91FD3145A752DBDFA26C53521585345F5A31A1AFBF31AC2DB702F28FACA51FCD577FEC7397B2405400057B44C5A0512785377B081C75F12EFD67EF3739BF7C53D736E4CB13CE5D58EAB0A5D575588A32CBEB301BB516021DFF09E8D16EDC2E3CA5F7A766DE5AF412867F65786CBBACE0551E98A25A3ACC07EB1A3E2A08E337F72BCBFDC18225ACCE32AF7F266818DA10BBCE85BC042A76BCF5481DCEDBC9BD13F0986086EB0E741CBA5116401AA08336F73B5AAE77758A72601A03CD94600197726825C838B3B9F2045AD2D5342ED9380FC714B9F5FE9C45CE9393BDE2B3CC0FD3D77F16557BA60535432ADB5E8791C495B60A45EC042378DBF3992BD3E40AAA8BF66EA9ECF735EB67B1B2A5A5CA2CEDBE06068423D62D572255CFFD3D01A235DA5A5BDC2EC1449B3B9F3FF232CB09D384358DA197FFDB27ACA8D6003C2C261108823F383FE3DFD4EC0E295AAFE4DF8537EE883B3513AB6AF4C4AFD6C05A12EDA51C92B8FC466B478FC9B31A6C4E3B541C99881EB248DC13E6E8751B46D96ECE34F40EEB449014CD59074FFBFCEFF66591C52E4F6B04535C2F134B1197B99869C8030DFD15D84B7CAD57DF7EE134C91C3B6AA5454185348DA517A3BDAC735B33F0D2A7DE032373E52D5FC0AF626B882BAB7F2EF093DBC776E1822A7CE2EE6639B9A2F833DDBBB629237B29A2E935004D215C51D025042F886DBC5077A029B095214E8FC7854670B3600743D1F1B3594F047AC77048A1C1B2668B59C67AE95D567707C5EDC3EFC4866879E12EDF53D29BF1C183D84CADAE03318FA8277C5816658F6B425AF427C75B754EF9C38907C74EAF44912A9BE463A4D4E6458CDFFD8ED6763F25C3D9590622D4E793023EA06337F0AD985431463FFDEDFE446B26929B4A6530781BA584532E4C2BA14627C9F0B7CCE3150B4F5851E10D5F3FA9F6A42E03146A1A10A627DD92A2444C17D9BDE40E8ADC6BBE617BBB0996D315CF43AD16CB64B8FA24F1E07A0E4CCE6A1300EE436B8E3EF3279EFD142A75F131FA3279512C6ABC0F28D84A1B2C0EDEC6FFCFEAC19F5F6C94E2528883E4AF3EDF3A297E0235F47F18A17EAD1051800652B767C4BF0AFD56FBA6428B7217E764F435FEF41D7A3B621E20E0CF69221337BCAC379E44FE43FD00DD5CA5908A0B9FBDAE01783672E29CBBD1B7F276144DBA9B8B6129520B693808A9E7C76A68FFD111931284C77F0AB8418D55F91ACBA03F44593856C77C7F473417F250A2FEAAAC16D259EADB31D27171440407949B1F2912A6CAF58F9955F8FE99713491092B9479AE850A2EC7B7C5A130EE9B23A1AC56D2BEDF632B75D3424A01CF1FACC903C744212D93F044E22019106C0C662726C52DC92C8ADE5D9BA91B58F5439751ABC638E65D6939DD8ED65A947DF54BD35E4C3CD188B6288390B1421BCC92661703DA704AF78C05DC054176B9A115614525D84A05411C44B183FEBD7A860CDC09467F8E409134681460FD45FFF21A4EF4716D1546284BF8AC32F96899D76E391F3050D6643C1C32EE49BB4D0CE850A246D585032D58F9A677A614E98614AA53B7356C5B4044057ECEC7A8AAAC312676257C3B86498298E665E2EC2DF97BAB727273E63545EEE701E02035CD63253DACF7CBC08B27690D8F85A64E72076517832EA5D2B3939F118050D89A7B17AD464A615AD1459106D48EB3C2BEAD6D9BBEB1044FF296763CF5519C19BC5AD8A6E808B80BC0C14DE982A7100C77CBD08AA57E6ECC2363969FA0D03C0A70334E0D891EFED98A1B935D0ABC4ADAF5382F630796250C7AB6ED5C653A9DBE7770955BF3A03A473EC1224AF8ECA0ABF92FF07A7A8C4E91DF8684C96CA5FA6C528F61D1D5E3C2E74CE982B0C18C241CF6E18A049B477FA52E6BEE354F79CD6FB8EBCE876E01FFC8A72777D558CA88E2E3D376B7788F254BFA1672F8DEC36E35037FDB72E4761E0814C02F59098DA1976B4EF18C3C95DA30BB36C14CDFC9DD1C9775C0CC6A80CACB777271438829F4F6F87BEE68D48A875EAEB2207DC849A60BD036DD4A7EDCECAEEF5F06743754BD166F12DE4CAE05A669E5A5153E90A0448935E2C692C4485E78E6E5A73D764405812551089C87C36492A2E34738F895FD4D57DAF324F563B69DE5F373F4F723434B605FDC221B491621D0214FB9512BD584203C29DDA800DD08F107160F53659D8B755F2FC49F1FA8B2C47283985A5260BF622052D0B7920EF23F7776CC1E7D3118D07867C0BD20CA80A60D928EF0D64268F1DB2FEF8DB116D65F0B1EE7DB6D66608EAE6B9D573C964D0F69ED8674A4AA1C567D8EAE3EBC53DA2B7369E349F36EF7C4DD34AEA701F3C876FA314706C6ECD371B106CB1F1BE02483F9AC50CC8BCE7E39FF84510BFCF5A4DA44399E86EF902F3DDE79C67AF35F3BC3934AAF510307AD8B6CFF9FF5B63235D57F8903B98DA013C741C3428B56C046739B6CC0EFA0C03C5E4953D50D26C12E8E62E6F13C6639FA949723FDB6D56FCEF39FCE897D7102A8C43BFCCA4C258152B325D1EC0A59334089F7BD63F15C5BEB99068B240D7E5FE892F0597B4732C94A14B39C3C435A01D31AD8311E857FF8C47C576ED7BEB030A0264A67CBDE7C2211CE2B5CD736C6B656F314A70ED909ABC4E1C32E1B0A09827166B4E2E8835539C3EB777F63A9360066962637D660173C2BA9451FE2AF3F6F7FFF5AFF7EFE6F41D157776078119E375ED5D6C73711E3B9B387ECD8A06570AA6B6C0EDAB12775763250EC72AE936570950851D7EF303CA26EB17D55E55CAD97CD00109E80DB720971C9A8EFF7767CEBC81C68003F5282A8DAD68536831342E75C3A03CBBF48E22EDE3755F34F059B15F879A35F757505FBF08AD8655392B0D8E539F4C53DB9CCFE8138FC268F42AF408E3185FF07E8F61B1EAA6FA46924A16E65551913911C0C705D26658FF42227DF851A7404C3A0082BAC3F0504C8E8254EFEBF046C7508EECF2183430985F381F9A39FE531482A728683BD221182415FFA1E9AFB70D6708B511325BC21C623AC530E45E514F5F389CDC32CD0D2A65FB01E39AE339519D3848A47192D5BEC78E5881795B2C18037703D79A2EAB9BE5BB06474F23ADBDD42171E899BED9EC44ACCD96719262DC787F6C4CFDFA6284207502C12152DC25FA060E7C2BC90A55228C26DA74A94DD69E1DA78B97B7E72CE22D07EA33EB83FBA0F1BDC65AFC4559C9D7A4B826657FF22AA584BE89DEBE40E4FC69489A16BD98842F27E7CED00E5C7864673FA3383B5FD38353230AD205519AFECBB4EF009CB6EEAA912E7E8A73D6F0EA9E1AC743CA050EBA10115E5A1FFCF3F27E072F98134776A0D3F0BED9667BCABD9E68EB6BF4F46270833D34C4A875E1F17C4CA0F8B6615B2DBE9B2FCF1252E2A528BB5F5B63960AE4B7174C9CBD99ED1665E24446C93C549276A1A48C336D22208A7234FABF3B984574AD550C030D60DD8E2850915871093F6534D60B392667428BFE76AF04A4D34D7737405AD8274A514540925720C873A212F25D63F2B7A181BB6FE266D01000E527C5134994B99F630B81DEC3371E5B1771B745B0F369411EE1BB53422D753168B7F055413C08221EFB76A63CF09CD9167040A8B961065D8F9BD1BB75411CE7DBCE4671D812A603D8A9CF932BD070D966A69923CCB3203343F233AA3FDE52078B17F53ABFC22E73D515A63A3BE56616FC138ADD84D6E2E3AD1F1BE1DF698F8CF4E72B1E3C3ADEADCDA90FD9A2B6C424516AD28DEF9D96BA82B0835E0716B80AE3BF78D7F0B9DAB584C51C540342D89268C316931851EC580C7F6A2AB5BA05F98582E19DBE167B9DEAE57B78DFF7D4F6D322D8BC138DABCC44B4FC97FB514F2F4AD0E3BCC7FB6DD1C08638BBEE1C5AFB722B385CC7EAD522E5D78B9F02F21AA53079B499E70F5D450C58CC9BC4C79624DE65BD4BA8799089A7A32456DEA32393C6753EEE364F81A0196EC18EFAD4E21914A446EAF8CAD124F1E2A4EEB54F3B60B7A99D50D9414F488DA8F2F87ABFC79FBBE3F204A6D61870D46B3B2F4DF5ACFE088A6B4D3DD966F8A35954FE1EF07713D6BD849D64366F67711FFBE2217A177F6F28115E82BFEEB6F2F007083BB2B75A2D72526A9DAF638A94B714E4DF066744CE1619D977E20F1E490FDFD2E3976F650DC58D5D7B1052D31F35B95D7ABBE7DCD59B876AC99F0D162ABD467EDE78ADFFEA4D1ACE20E949641520FE75D5C1CF14EC21067A2B27DA8F989BD0ADD15047886AC273C7DAB8C1BA563346EE26009667414631E71B3564AAC840847A22DBAC0DA87A208CC81CC22D2E0032F62D62AB77E2299C2CB44DC9761067A9C083D4292907919C85F0E8EC9394497F2B9965C1455C0091D3AB8146A4D0664C5B24D0DC5F8FD23DEC1BF7D6D6203693D3C8F447B754C9CCDBE957863F534F69D4A1365A5A18648442CD5A53322EC1AF72287ABD92FD82B1510FD84017C0496C0C643D4E457C2FE492E2FE3F4D7A16389078FC93737B8A97D5046FC941EA9D291752DEF205A17A9761573F9FDFE232EDB3F60292A8AC3E23D873DC1A88C0712DEDD80265575AA92AF1AE787EEF161CE164B5B9DF9D7A2AF8AC605BDEEF0C11E4345C3823E86B63B7CE5D7A4B88A2E2346FD9FCA6FD90BC83E536F2765FE3A625CB4F147C834700044CF2DB7872EC8884F808FDCEE5D1D6748FE545E7ED3D8E473C4BC2EAFD4216BB7C5038072334B4F63526903802EDEFBB056B0FB76A768D785CC4CA29A206E32961ABFE55ABD5BB0DB605004F2B364B09EB48B68962F13512533EADC6FFC65EE25535426332F928D8C30499C51624825DCFE28DCC31BB6A68FBB22CD4F0967BA1B361C081AA1E9B73E8FCA6610445861BD3F0B37DC3BBB19A36E726D46207F3FAA4F1708049055926633A441FD9E624642E4586812986615477D6FCEFBD1EBB5D0E052918836CA5DFBF1AD147AD9AC297318F74F22E07F3157C4B7DD311A2F3F93D66E335BF5E2F78BC1BC8F4967C92467889D76226F5E92A6177906E7D6ECA48692AA3CD5358970E54719886BCC1C394601E8D4F439E3B8C01EC73AE2DDC576DFB57C5F5BE1A5C52257461E9F17056878B49DD4723F16FB3A9F8624E5F5A4DDAF0847E41F815A8817CBB42D606BE9A184B4059D77EE30C64DFF6A8F27A7FD2E878B70D9BA63C5398BDAFA5A3B1FC2BCBA6EF9051E12936C7B3647B2E1C48FEBF6A7CA1287472F0F4F5A274D0266B275943DD48E1FBBFB41A967DB119C1DBB9B99BB1D93B2BF55CCCF83FD17B8DBA7D1BEFF995D67ABABD7FF4B51477E651FD8E1EE7E650C6E160E8E3184F9AFA3CD2B7D293D25D831C6518F40B264849C74226EA8048C79F786379BFBF1BF97384FE6DD2324924DE2678FE5A4036F45E0B813FDAF968A523817F921AF4C94B6611C04E41BE91ACDE367FEF119742B0322AC0516A1C270E2D7831FED91776F1904C81877B74D93BFA6051F1FAD2C303A37A1B4611FDC1E57F96075B37AE6A5295BE842161115052BFECC8E9B69266455C914994822423BAD5791EDDDF4C81C05FC7458AFE17C4F6B5FC9E9A7659500F582593A34525D56D5C3966EDF25BEB2A4B0E54440643705C02E6B96381E4A21E8DD797443A5F4BCE60D31191FC6372921C2C6815562B8E7B81AE1A827A1AE2FFFC6BA7CB9F61399A91F37101C1DB157FBAEF6F20A569C2BE79608D2E426DF0929E4B9ABC8019BAA5F276B83FE05F923D3CDD9B45B229151B20E5FC011A6254B8DCA42CED3198C4B453D1C43B386106F40007C05047DC1884719D07BD9729ABE87B0B847D95845AA31AD177124EBAD08E5A935801862A7413F1241C7FCB5C24E3D204A6B982E6D86198552597C9E35CAD46CD668AA4087CDE901C6DEB630E92FBA1DBF06B5415AA776BE410400FEF562D86267ECEE07106981614EE78FDD3342E1003DB418546FA84AA682A2BCF2001B3F4D5D94707A4B4600141BFDDBE6BA9D704F331EDBE9BE3486BC5C3FDF94BEE51099989F10F08115E29E6DC8C2C6F9C06278CF8550B8E0AD0BA79BB6ADBF3BF11A883E41B54BD588298F9EE03ACE70CA38E9FAD11A403D143A34534F266CED15D32C85509D5394689D715A66305A26231E2860157B479B36AC47138EA96A75ADBDB01D115B820B310DD013B81C0CB7E2553CD2694DEC474DB5A468C260E5C21A9C2311414354F5810E6E34867D9129787E4C64AED7EC64CC556D16CA6C96C2B4264C5ED6ADE8461AF305F40793978DA2F99178EF33D7D7599423E1161D0F0959A6B5CE7248462D9A16E15C6CA67CFA9DE9D977D8FF9B24C52F991077E34DEC41767D6FE22A5B5D9DDC0DD2CAF294FB3CCE958652B6250E2A8EE1319158B38B21252B467DD5522E2D7E68F9EB94169794DD7C514A29CEEE2FF507937F62EE8FB90BCA1B911D1BA06EA1C8A1AAF598C0C81388E4FD0D2310F4AB98C56987B620F97853B02AEDC3F2CF3081D2674862D754F96D0E1FAD2796C3310D84AB76D512403BFDE5C8141C5660E2FF42D2E89DD99D3C364017C031B917694122792D91443DA5C556C2D927C53664D63B17C8EC8C63D8B45CA3D74D0B7CD9B57D7DBC591D86F001DE976764410EEBB57151C31887490DDA396B81C49B5203FA8BE424B36770A361648DE5610D24AD85FF0E8BFA76A48BDADA9D99ED220EB1F190D56A41DB7CA1684C55F9FDED8F2FD672998571954B9ED81DB3C8CD5E71DAFF453E87EBA89F3BAD615505592B4C2EAFBD5D912DD8FBFEAD94F200805064160A34111AA2C43FBE66E973D27D5CC3E0F2035EAEF6B186AC52A2512CAF788071FDEF03E348B42EBEC6263896928E498280F58B99083CA3B10A19DCD283EC94D74EA3FC2CD37AB5A4983914ECD4DDC2DC80AB8FA6A95C945A7CCE4885367939085C9E97965B160635723C2A6EBD15852CCB84763BFE22E0D87202024A824BEE0E9E164FAA0D0F473324B2597486B9E27C010C90C5D113163B0A9CF2B29C909CE0951850424BE2DD4CD21B502536C462A55ABB4A3153D0A86B7232B8CA0DA55443F1DF4BC9240F80DD34789176421AE067E556346296FCCFE47DDA106BDE6E469C9B7B88285B4376EBE4BD777C93DC16858B8C1AE51D9BB8C8603D66570B7F63885FE41A03FD0C14B908A83F8A463CB38D3E02468966F1D62A9AA76063F627E72659C0593F76212BA283BF65B84A100943B08AE7AC6BB1A718EA2D17DBE0C2C387FC43ECF7C60BABAE526EF7BAF7C3AF1DA32909AF9E575359219A96FDA6533462689C2D177D4A9C2BCBB23603387D55C70333098C529FF92ECF72E525CF43E24FDFDBD1E909EF188DF48906B2145472AF71B461FB2A7132D5CF6FAD6E109FB1A7A48F966B0CAEB6242351F6367AA96AA4C71F50DF33FAB9669CED4FC01AC733E16B46F6FA303183784F8AA9C61E679C7EC09CCC29A5BFBCB671630E14DC60D467F0C05EDD74D307FBA09CFE3B2114E9263F50DE50309BA45156D428A72B7F49DC4168CBF72D41686D6A3F4943917F46787B879071E6C00BF2160E44EC5505A9DE52862786F7B80C2553200013F3211C3D936D675566AD37148AB96B62CFB40EB928D4385CAFDA3AE87183539DCC366697ED0F04C2FEEE86BDA8D256935CA0DDE2E30D26C91FA92216928B1E2896FF29D8EADE611DD5F21EEA0D6B6F7A57DCCBE56C51A74F61E8FD242917EADD4149290E9ADA2361845C4BCD4814D0245BE4CC17B84F4D6C70ED07C2C579D08B782B6D0D68BF460D3214E320FCF4777F5B21DECDBC2FAF9E0F5087F7A683BED41273C21561F4C2D1D7C7D2053D168899B94EA83AD51BD706956B1D6685BC6317C32C26960980B9FFF3D2131F691D7A70113C23F82F61A4BA74F06068DD609C0D64E38DB0D279693E8131ACCD8F1F185C4EB988067DCB4AB4755030FB552A25E294EA9EDFC2EB29662AADC5172231EFA9F928022023582AADB16A57BB182806D6190997217B1120F1F0425BAB2273C4EE65B666283055A9B5FA04E6A13A8F9F547FEE7DE8ADD1A3BDFB07E9B4C8A71F786DE7CCB74B39FD5F31AD5733F0281B448EF7F8B6F643176623C532348D0923DE10C23C3D9C05BC6D40F3A25A6D0B10456D2E93677C783E525BC5E4D4E72A041A02A65E9A5F32FFB69B9CF3EBE13CF4A0CE9BF05C0BB49675172843C61905D28AE89ADBD2AB587BA15695AB7011B230FE0A5A33DA46A3DE53F838C0D9F98283978A2066A350788D5DF3592E92D87FCBC9799C439E32FE0F467B0C49E8B06661805D117908BE3A2502958E3CF4F31DB1EEA12F93CD0303E9B69479986EC54309FC84831DCF9F71850796E6F02D733E52000DB469D00D8F3C9C77B37BD9626693683D97B4E4D21213EFB93A4C48305063B03C574C76E79AE443CCAE87961970E6FF9AB389C54FC8A3016A273237BC5D45720B7D82651F8A6148A28BB931FFE32D3CFE9FD0C95E1CEB614820857BA3AEA8693CC976AA7AFCDDA684DDFC6C1FD08165159A3A54D1E6C784CE7B1D8EA359F2175EB9AF696EDEE12172448CF3248566FC65731B335F97F81032BB658BC486D9B7D598025E8B45F5C70D00DB2D66465C54D1A16A5C49560622C851308526C0EFDC116205C39C6310B0912C5E179AB6DDDA6721D33F11218C5AC587D038336DDA3CC8325C8E0912AAE814AC734AADD65964A0BABF81F7E98ABAEA8DFF2D080490668C123A5F92425252D9E7FDFFAA91B86A9B6700999DF83469793E5A3955C16555B7FB133E7F6982BD53FD7FB293FC5AF3F89F92317705480A6C8F881FED1CD1FE1622DA6097F302AE13D95D3352461A7BDFCEF892EAEA58D7768C99D675871ADA78A46BB558B34BC7442ADF5E72878F7F39B124FE510167EBD74E95FF1BA1AFC4E71CD98B96987AB1318B1FB5551ED295D6614287156BFD3E153E01688DAB135CE6370064664B8265E604020CE973DB77D2AC4462237371A0893D8A7A3D188A2F226B57E6411B4720474986A7A60F01AE0BBBCCE9BAD9DF6B0580F211AB3919247589A14D4BBF245F5D84D8145B20C31B030C491B8814007DA2ADD59E84FF5FFE027E54A683C509C8A9A5F8B3527D2AD6A5EDAAE349041A369AFCB7DE463A668C8F6D4CCCE7D09770E39E61959B6C21F543B416BF354B802D432F364CD40340BB14B4EEC95F0930D156BB99A47C2F5838FC871387051BD93B1973E375A84090A0279BEB6B476F26C47DE1171A3AE91E77039BFD9BA1EFD79CE655DB6A6ADA3465131D28523C10B0B345E982096EAE1B390587EFBEC4735C5D6B28DD12B45824B13EB2A26D4BCF134A594E46C3E899D94312554DD97D87BAA1D89B7492798FFB9234D2C92BE548C82FABD61F381EB69B97C5C7B1CFB9CD4BDF9B15B6186D4C6C71A53C7AE533F0425773138C8617CA9A49399F33F4C799E2797FFAF07A1710ABA2ED3ADDD848218825634D3FD38DD2F68B6BB3A1F3BDC6312FB890FB3033D028E6621013F7A0E53FD5B21A62D99D39AD3386BC8AD9E4A97D8A7CC6E3E735506ABA84705AAB1E668A63CE3D330E4AE4583926EF3ECC5B9C02DBD11E3948051D7B35E7D0B29DA21655D336D7A24D5E8BD81C12C927B43653AEF54F6C21EC6015D2C440E5175AD2B44F3CD493B853D91790C8887E50175B2D15169D34FED5BD5249F6F4975FF87488126DB51BD212A404373C7959715947E365C911DAE00F81FDE7498C7AA27BEE03B89725E9B9F57AACC33F575E1B6ABC470AE9F089BA2622A0D9D33311D55AEA0BBE4783E95DD5633F2DF8B1A8A8AA5B85A736F51635830A6C72D66FA2D9A7EDEA0E0B114A2E5085025198D3C09E7DD414CC63EB742E7F79A716CF1E86CAE5C7174778343EC56A5B96D9CDD32E2A5F0B072D799B77008C1FE51C06848ABFEFB3ECD360AA6B00F4C16261F1BC713EB0EEF6173E3090FDBE444A2414B259BB93B16163258C1C5905181B09C7229C65080E4E1C54C94E208CF5A96DF2FFB1ADCDD95A76C83DE4CA2CEB066FF2677A46C3FD70DB72C4ED1F8AF78A58AE0DCB7F5BC46B8CDF1C279B7894D4548ACBBA6367B190B9B1ED65048790A8B81A1C18E3D6E16D9BA6A8B435DD6C523034E72F410B5DC600A82AF2A6F9D51FE23A7912D3221D320CD6E557A9B195AFD8AD81ABA2012F3E3BBEB6FC5C2871E53DBD8DCD708092E1BF7C1F85D4A6C759B3F85BD6854EEBB03865AC1A6C5D659E34078BA0FD85FF71BD2F40059B955FFE075B69D875CED443C8A0E16A1D3ED8C21684A2A7BA78A99F00CF3CD1A9362AC16C6B6D8D5489ECD4D0EF02B645901C9A7B93B43D28523C10B0B345E982096EAE1B390587EFBEC4735C5D6B28DD12B45824B13EB2A26D4BCF134A594E46C3E899D94312581488CA1CDECE76006A0DA2BE63059BA0C98D76B2DD92957C6F6C780C25A3DCAEE4E78A5C7F53F79D92329D76D6BAFEEA4579FB9D4E57DE35D4A84CD50C982AF89CBD30512E4C04E9587BB6F8FFCD78D290FDCFFF1F1F7C11E0476175A5200CA59E75EDB8DDAB8D47E372995D6E1AF200648BA22E2D995C79D9FB32FBB0EA94FA66CA231EAA20106C625B77798256EC470F98A78773760038ED39AB71B19D5DB3EFD3B77E206A5B95C4E9CD12C5D5F696B7FC7CFACAF4495982232F8F94B2969F0A774B67FE1CCB5BE470D7C156D0350318FBAAD273FE5AC8DE1AA20F43438B6A3B408DF01072694CEF830025623E304AF3B62E1C48120E144407E7221035D32F7BFD5E3508455538DA1D12E0EB2344BD5DAC76110ED53961A65AD381BC365EFC785EEF542B91B40C685DE0A0580AA9A7394FE39D1DA3D0CFB207875F4408E851EE361BEBD533627DDF4657B10FCD25737B608E27B0C2D70924E596AAFA5596C2165C1CF2CF536A2C071CDFFF3A1F44CE51861294690272B9D7829A99A9C3C918AE2BA194EC567F088AF2948A2DC2A3EEFB95D3B2D7EECFE96C14087A55A3C21234D35F7606016CA79CD65A767E42646C31D91786A3F6A6073DA31393C64529453B930010D0731087F99DA4228D626D2789E371A9812F12397F35A9BD01759AA533DDC1198E07FC8FB00DF6CD9D7AFA85086FDC9515CA5CE5C1FF2411585C15CA3B03C4E7EA3B3276EC6768DA77F460E5489265C3C023DA7B3C992FE08F90CA38C4F6C058B09BFC3EBAD4689D0BB5FC5EF395BD8204C8447D3B993A137B0A05E9800F97CC7AA290D4D519EF8D7221B7D44850714142BFCFBC2EA44D35E942524C981763076086D3C457745B5F4A73D6740B8F7AA92CCB5A5809DC411B50FF0E7E3DA8775BEC7CD683F4FCEB2300D09265E5387E67EC193B8D4DCB33C5A0F89575B9E54DDC49845A38F4BCE0125EF1AF735C38448C9C4FAB3D92F80137094A7B0F92BE205C6BBBC9816E1E9BB1E6B500AA377A91EE3FAE7CD4ADBE13AEAC7101F65AB03920B471C451904C8B6BFE41FD5EF395BD8204C8447D3B993A137B0A05E9800F97CC7AA290D4D519EF8D7221B7D46A0B1C2B89D0CC160D61784E98A2C1AC981763076086D3C457745B5F4A73D67185327668E388C1CFA1F5E9B5605FF3A4555E75EBC3ACC2034F97F17D7972692D5DAEDB47CD4E91B3E34E055CEED26A6633D0F0A1CA9D3081B65AED250C648128B299FD97AFED5087B52DC541C38D5556713333168845DEC8BA4B19DA49857904FCE7E3776D73CFBAE75F584289BBEA2179B9F21B46D1088AE2E36E2C7AF474BE103B591DB11D01EDD54B71527C661A7084AA9098E7F9134D256791F9FC5F649C8CAA30A2A640D63975FE3031F6092666D05981C85415ADF569AF793F147AD7DD2C54EC1245BCC2BF127D2BB95B1694FBCEC3FEE1CFF277FA034FB3398ECA4329447E00D6286DA0645CE08319CF8C83C595BEBD034FAF7B37C04CEC3DDB8BD74EB3ABCD78425C0518B004D1B650DE65E64AC1315B983A64F6EF560CB48A49286DAE9BFA28FC8BB1C84DB12A6D1B0188DF6CEF0AA558731D53BF82607C82014747EDAE6DF11D6AD59037FE7F2C9718BC9CB5DB73555086A93EB9CD5DBF867090AC107966DBB61BECA17184A4E8D0191AC4A665AD1FF7413A4C07D72A0E28712A86A7AD3DE6E3EA5CD42D6200CEC38E3D92D1C6B6C101B620BE98DBD64685E7337771974746EBC25CF6F0BC2B447689D6C25E140425A7CFC81C29B6864EFC0FCA8A228393446DB215F975917118BB850BF09F5B69F6EF0AA475A5AF36D29415DA0CA7DDABC9DD77532CD72ED31436CD3A25B6CBEBF886E75BB545313772BB84D969E740331149AF9DD0CD2178A97C1EA7B49F9ED3423BF220E2E232F5A95495C9D135F399F6F35A1EDA6E2A187FF427B92D650B0517C90D8BD0E8D2B1C9C27AD2156917CD7A6CEE705742BC44142B8553BC7F59E5C8D0365EBB8BFAFF6B9486DFEBB6DFEE586C14CD04DC913110CAA15BF8FC1B21098AAF5A52BD10BAB0BFA34564BAD68B5569BBE811907895657042DE014C02F79A07C93440C2D1A0BEF048FB5D470F858E79F3115CAA7E4C9F59E7D7486BFB1BF8EF2EF264F9BE77FCC8F41F5B803C2A70B80E6A7565F9D3B1123137BF6A27E8FED2D5EA5DD86EDC8CED518571E00B679A0F5909CC12A88D8F16D5C10623B572ADB922D7665D1868E309E747CB1A9F948439352ACB73262D29FD03FBDDB9B287F83B1BD9BD2E63BB180887BEFE255BD185D4488F4643AE682F5DE1B518E018AEF407D1AE64F03F91127F1CB92381B3B02A511C5853A9AAAD2DCB59B1BCEF314E1AF5719B5F28789AB75A4DD67512D446F4205D121903FCC086EC0A2C4BCF650C9A52C3A95F21E43415D231FB0B3693B1DCCC34B85B83C7AC395429AD6F752D9919CE9BE8164B5659A6F9D6E56F5437A2E93AD7223D9FDE9AB90855E8CCC0EE28C1F2107B295FFED3A96D35D1D8B7F2433EF91F62E7F585B9ED1D60AEC14941D21723E7EDFDDB46F923E9DAA08061357F371498C531E0562104CF007C68A770A51B6FC61DBAA3CD81F1FC7F99E579FCB6DE1862E72C4AA12FAFF71B3AB248D2B1FE10325FD4AA8B63BB537B08CFB70CE8E350B10535ECDD41DFB2557014AB0FDF8555131E27F73C6E0FAF3A5BAA1743B65B8F48CB063AD55C78BFA843A105360C9723693E8879A7C52AFF19F6E6925FC33BE1FD55A067E69998D396C89E151172B9BB13A88A4452090EC222483E969C2DA200B207F307B375532EECBAEF7E95C62BD28FAA5AD0B52643586F46E0CE72F17BD318768490FB55C3054AF111485C375895D6E7986347BC95DABF00A18470374F646FDBB46E0F1E3C1B4500B41CB7AEA5A2CF3DD5D24F613C341922A741D0041D647BEC77DE5A2C9DCDF8521D9171123737621FBDC7FE810F1E2FFDD7223A07F61977D3424667435361FA15A6FCD0B7B6F7D140A977D7268D77D3E8D8D2A55D0F10739ABD4851B0637A350550F6B893627D592BCA6796010586753DBF9FE729B8D67CC769961AC127216DEF591DAD59764050F5DB6B55E151DF2B7D748D7F27677FDA8782659D536CCBD790C700B143066A932E5F6CC30D027077B7501A2B3C5D77AE79B9D78E685266295F5E106C0EE76ADEA857B04B5DD6EE37897540A34FF40A9BE08FD4523576155D02484BC8E08717A6C14C6EEFDF01B9587805B92E44F99363BAB198549 \ No newline at end of file +22DAA16367B92CC030386164898346DD1C0609E5E4216F8DBCAECCF35EF70F55C25CE8F59EEED9164FDD8C3D453708E101E456346123448D658C94C0869AB7674CE7EFBD6258F1FEC412F8941F11017D143F2C4CF0FCBC32A3002C132208834E3C52CBACA4AED32A44BD9B515936CC0394704099B511F18BF3F35BCDBDD1A76E49A45DD5DA51ADB54014B3284BA7A5BB9A69A60E35966EE12ACFCD5D4AC4EC96CFB44F8B15BEA6CEC221FF7B90DA9FC027927A6505257C3E562934F81FCF81CF6ED36E981BE2A608F5B01B6138500D16C720B560EAD4D223A280E54FCE22838AD070DD8219D1D5FC6D6AD204C5E584B49F419C954E944CD189340FC87B01EE424399AA4ED45AAF0B35E10D9B36BA9B493951BEC257025998ACC0C8115CCED73BFCBDC1FFD3DFD6DAFB1A065DDF8B7CCED61C73FFCC02076BA49FF37719AC60E60F11A75716A0BD6AB221A413F0E80A7A8F58C670B5ADFA7A914CB105EB8364CBF5763D2A8BF14072D906D715FC779F36987910C29832E56A9573762ACB105EFEF5119892059422CD79300EF60408F05A1DB8AD64E6B53C76AB9A82BA2DB9F266EE5ED7C00401B63AF4709C71C16D11E0E451D79F96CDC0F5A9379988B6413C9F6B41A0343DA3869AE33A69312BE6DF05CD5BDA8783AE53E3843A45A25A4A4C2FFAFA48285F419EA9909B3B43A89C53CC5F5F58EF747023111CBA085BF16F8C48A46FDCCF1324F2160C433AC7092ED6966E7B84D49C2809F015A45A2B2F8326C0066A247F9A630D74BAEB068918CF7FA09EEA004412A9314D6078C4157C566523EFFC85678C063A36FDAA9A189FAACB6CCDA183D4DE30F4094CEF3CC9613D5596017206BCCD7D9EFFB34203B7C3E60F33E96D5A288E494E030C79E81CD6698C494AEE621467FCC615DF4B4CB587BC4BD594EA26668C06FEB662676C5110D7A14D90F8D1B0921964E6F48BC738B160F3AE0658CB9487DDC904BBC7CD80451975FDCBBBF5CB59F7DFBF034F8B738375A99D1416696BEAB17C924E5D2D37B0FE5C116FABDACB5C99F245C867A96D21792FF7C5622CCC88C2EA0BE56B3DF069731B22C9116DA6A9D75AA8CA50E9555FE32EC237A48A5364F3E09E5D63961EEBF795139CAD4D79810EEA914B014D0A05E4D9CAF883EF7D94E2432FAA0B657FF9B71049D7EA0959096B941DC18792A1746ECBF91F5837728DD7DF365E7D168FA39C61DC65F7351A35D7172E55F10F03197686ED6AF14D8C5AEB941A35DAD514D58D84C3D920DA793D5CFEE71C25E53EC21C1936FCE766119A6492CBB9B67925B9DB30B75E2391D8DF684AD5DF08B64F3DDFC31FEAAF35B5CA72BB73BCA95CA621C9D0C03E877B115EF2B3988078E83AF83D2AC691092C7AAF8D45557CF4003D4FA67A81C880EBCD8318B37C5219808335CB7F8664E176769B1BACCAB58E0E1C8B2F7B06D339FB38718653D352F6A5B2FBEDF758F2AD54B2548DE7A343B23B8E7B437C1AE212CF0DE693DD84ECB9D922B756FCBF8F67C143A90671A7A0DFE8A08063F24539FCD1579DAAC2A6DF8BA36B6DC901FF6AAA05763A10334ADF0381DF233A56FD68CE17F5B3279C1F5CAB7CB1D8FB5C490DD23B77D895061426287D96106858325AA4E666605D6A1488781190781DE82AEF9EFD0700D189757D64634844EE0EB21F152401DA3527A75B29519B9115B9A5CA3F2C181551079205A874877E61BCF897C2444DAE41DDC644D8F2635211C6A1851AF13DAFDE63DD929ED87434B8C2E3BC0AF17040ABC43EEE2F7170680AD7194194EA04AA55905F746778DB544F9F06013E3276BF535FE4255383F31BDE7F5F9CC241A7EE71CC839F57C6A8356B89BEF0C43975A1381FAA09D7CB1C0ACC85FDFACE418B994FA2A86E0F4B55E17E40830FF0236F140455E44063D126F164DAEC12BA124D2D212D52311103353E5D7E6BFCA89923F294673BD43CD5DE58C051BE48F7CBB49687F675A4EE1A407738713130868401CF272324A3675A1DDE2960FFDA9065B1E5479E0B62B5E36C8440FE50C2AAF5EDF7FE1001869A9A93763B9B805B2628E6759A1DBD1A68465709D52B808701E5ACB87E68AE661BE8B3CED65D6D57D23F3680E21C2A3766D0A13AEE06E042C973A04A1D13AB4E320AE59DBDCCE0A5DE7B3E6B6D70DCA38910B3267F21CFC6D5457B9C119E1AEA4CE2DEEBDFBBAB3731FFF612426DF576D4A82AC5B2C043346B152E1632635C708D6BCD21902666EA42CDF002D526D91D37576197FDE6721211C47EED3F1D753219E8730EF4299D321AEBA5115C4C99DD532B34044CC1C2E65D4421BB4F28B9A10A0FB6B1D23B1C1867B698C9DBEE0600FB29AEE4D5661D128BA572B285AD7E646F689D93CC5C1F41DF28CA28A402BA3036745A6FE8C783E4E5104CBFCA723F28FE4377A5C9398592BE67BB2F5E8203C76DE5197B39B1477DF3FE167E667B77D6A965F98B2CB6AA37C8AE5707AA27B3D6367277EF6D4F90DF1E60929189CBD8215AB3510D1A62935D672D7DFC2BA16E204B77BD2E8BF34FFD6AB21A87D147349F58BD8F9245B8B396E0DFCF23DB0DDEE7A32DFAEA6E1ECF18DDC32E868E1C2A54CABCFE97D08CAC8856F9353A21E3E840AF5DD56450F474F1AFFA6A4AA5538B903C2B696618BEBD087612F0800B22A721993A7285F462F30CA340A093A37E70F49FCA876A3096C23A2E08DB4619B5C48DB7F3FEAC8DEBD60642424511DC26DCE6B749FFF58C3905D0E095768771EF820E0944BCD2DE87F551E388DAE0CC5E81653CC9F82411E6B84B358B6F2FCF3933A356AEB2E799163E163C6A7D79FBAD027291C77D630A652270F10ED4DC9F7F6AF04FD21FC7257C6079DF692170E0065674323313911BE264C40A0070BDD9E631C5893070134DAD54D53C9A47694B3F731AD6A6D45D9661A9A5A0C89614352199E3E38911D7649D40ADC731DBF8B100644BB3D836CD15A534CE876D98E92810E0A22FC410F6CB55D224689E2C7FC6C6A357D2143105CAD937916EBBE2B2F683237566EECE0CA25A2FC51283E43C0DE5A9875BD13C94E3EE9FF71B77E5A410CECF084565F535DDAC9D1023BAF6F43D3850FC17E916B277477FA144978694FF61852C77805C28D29C8A19AF52CF3C0666C324AF9D77034C1FD1581179C063C0B9AC1D72A038F4B85214B2226ADF8702B940EC21F6F5C25A432E317BEFBDCBD735D60F8DBC1AB833B969E351C113114E5AEC7982BAC7F4B095C77EEBE42FBE837426409DAC0EA79589CB07B0437AEDF524D14BAF59A3DCBC8D4BF2B1C4F45C6F1B9D8C76427D1E242DF18A4AE933A8A3A4CED486BD0EA9277E093D36463C61E0DDE2CF5BA7E103689FBF7184F547BECD5AD25C635FA921FAC0ACC9903B448812BBDF67DCE05C28D29C8A19AF52CF3C0666C324AF9EDA4202C51A8100878F0259D6E78D637545421AF73DF114174D1B0CDAA710C0D4671D9936E9CD93307F8F879CB2CF3C50A1A7BC177FD4D38ADF97ACB09576F2BD91EF1D4A4244F665BD0969D372749A305C28D29C8A19AF52CF3C0666C324AF923815C408A0E8F777CD2583FE2062F438A7682D6690478D1BED2315E3F00E866C1AB833B969E351C113114E5AEC7982BF0730EF2A4111EA27B25DAD22F3FB483820B695209A37DDFC70561A7EF86EDD22EF31B834BF01F50873B6913E72AB018D5093F092F2C2BCD802D2B91EF5E179416255AE46B97E9145579367068007662EEF1ACFB3BFB7B5E448FFB764115BE3141FF35528F85373C71167B13AD82167895F6029FE858CD17B9B43029811056962059891A700283696F8175F1D805F14855A406C54CF4749D4E2BD5C00F782BB870946FBAFE98A4F2DA1EC3F4F1016FD105C28D29C8A19AF52CF3C0666C324AF902FD756803F2B47F0C54594198D273D6E2BEB8A2CCBD33215C84EDC6A48412AD9219952C8FBAE7D669357BC7B422785F41FF35528F85373C71167B13AD821678DE1AEDC5C49478E0D029291F3A98D315825CBEC7A61D64012300CD34FE07C5CA54BF1E91E1D1C6310035B73DA20D0D9F05C28D29C8A19AF52CF3C0666C324AF9C11E23C1D743CBD139E1E1F0459D4E4A0B58B7D69D72AA79325628E1B31F394F05C28D29C8A19AF52CF3C0666C324AF9B9EE558BCD2C3970430837EC85D734B87F95E78BF6A283BA9988B521A47A41BDD9C0EC00939DEE2574F7875B3B098A408873C10ECE16421EB807A62B13FCAE375BB74D628AECA3BD9C19C2A8D50946E805C28D29C8A19AF52CF3C0666C324AF9FD3CE85280A2D758C01B7D8CE889B8C24991041F9FEAAC90A271E9DB4D0BED2958E3028B6D30B2014121B7897A48A428E06B5A60EDFE80A70E8B1222310C7CFC1A639AE85B45F3836BB04BAB585541EBA80FC5AC5FB7FA13C70EB0D1CA40190FB5F8FE78C8D283EE9CF7E26ED287E1B27E90D85B3C77C0FCC49FE301727799C5E626F6BD4395121CEE9D11BD9160BF2201EA2D833D9F9150418E77D3A3B4F860505443C633C4EE6C4CBF3709FB8FCC64F400E3A9B3F97F282FB88C60808D00293C1F733615FDAAA5C180D12C073A8412BBD380BB60DC4773AC037BBEB78103C8121F28FE4C8E17F6C6F4B19A7DC5B9B5A189FAACB6CCDA183D4DE30F4094CEF3587A484338B82B7DD143C594401E4D0DF7FD608DB622A03F3C0EF94269EB2C7E93CB72F3764EA83AFEB2E062C34D2354BA63582E8187F1487390D031EAF2C8EBE6415815F5ECD7C4E72FBE4228B3E12F635136D3BCCA82845D49649510BB90BA43A333792275C86A0372ED608A6E22882FBCA2C83A2F7ABD0DAA21D443EE0BCFD4722C78C61A06445CCA2807FF3130A291AE10029A084CFE86851602EBFD2D1BE17240295A7E69C1DDA7BB48462DC9F3B19066037BA4316A1FF10788AB670D604FA812C6110E0C68D4B6BBA93A6A95D7F098755DBB6CF7E2CB170A3F6B271C5515514FB01789F488B28BEB235BE05CDA8D83D971DB00CF7A845EE904833D261E41FF35528F85373C71167B13AD8216787D57B4BA5CBB54BC268E0E20ABE595AE56F2387DA935EB666F3D77C59FA73CBBEA676F58A843E809AD48AC102EE1DB12A206898ED94D69EF0D868FDF7355E993862D80DC04D43382510D88042A0555CA259A39CAF911836214412D0C49A0E5AAD65666C9BC11F34999A4BA5902BF243C56F2387DA935EB666F3D77C59FA73CBB826FCD5378B557CBC1EBF7C22EB8631896C695C97340A74AB3740075489901A94722E419647BBD294C83945AE9EBB1FF5501AF1AC28CA9F579D326D8BE740DFB686F6F8EC98D1E5B61EC1123698B323DC0EA79589CB07B0437AEDF524D14BAF5545C9BCFF3DB20040F337F1F3906CD73CB78210273B70CC470466232637EE18E5E6AAE9AD4359D929AC271390946C40530B78BC343E2FFEE8A800D6F977C4056D2D37E4D6435E6A379CC5D16789CEC38097DC23581CDFA72EA11715CF62460D2D0DD57862A8897B5BA6D4F865FF0C7CE155CB1B0940975ED691FF19D416975AA26BD2A8FAF6D3BF47B4A005CD37F9C67A5E3D42D6F12CEE01091123478F0FED450BA1A701C48D9DF1D2C7088230F6BE5C8A4C1D328CF4CAF9B1B4208F8D295ECB44E688B0A2A646B2A1B815602DBD3EFFADE9A221E638E8515F390BD45EF8EFC0CB5D4C724E34BE62176CBAD3B55BAE0C40EC1CEFB0AEDF4F020CEFFF037BBAF92FEE5FDA909FB5F3351B903D965D6A45D9816F1139D03D9B9B53B69FAD5A31FDDC0666F1C85261F319EEFCA4D133CAFBFE328F8D948E781D417768D73F4EF360A4E5231E1C0881E56399787A22C2F68E27C6E3512E8D648B6D80ED3DB9166F41459DB9CB42BB93B94E626E3D2265C43E37FA3BB1FB8FEC735906EE68269E6F62D80AC7470E0B37B370AEBB2D49A4873E985EE3FECCCB41DBB671215B494FF18FE4EAA26A773012EF68EE008312BF91670BF13F16911D60DEE8AD0322286C713CFBE728A7FADC8C9381B8538018D173BE01CCA64D3E40645572AFF0F752AAF9F9659382845A813E9D4B9BFDA2D4B16D2E24332F42FCE55C031F02ECFFAC89B6AA504B445AD91C0709DC904A1530B2D7375226D33C653C73A18C7D752BA298969EBCD743654E9CC95C0A937E256F24D36148E9D70FA86C2C01CED746800DB5CA1B54A6F8D5892E1C270732993632595921DE2663DC0A230CCC13B4DE3312F941857E28E162653A9970AE066AF1F596122DBBDBFB30819FE0EC4A2C71E74CF86B3AE9F11A4162F96AEC0BF88D79A2A2E9D049C1F290EE19169E42E461C32F3D48DE379AF02366B794D540CEF1A6E3896492BAEA61CB5032811D9D0DD1FC788D2056093F3E14D5B1CD6CA96C7543F8D80E19E4C467306743F21A7D7D2C18DFC2DDEDE608F9E1DB7C4AC7CD6FE94A3C64C24E17240295A7E69C1DDA7BB48462DC9F3B19066037BA4316A1FF10788AB670D60C3DF3306F19F62A69D88778E3EEB1A55C83404C7B4F1157290630B5A5A6AD34BBE48F26AE5115FC5842736DC21532D402EEA945DE13F572031A713FEE8E3D47CAA36F7B05174FF2D631FFAAED61D4E56A4BB744185C2F984E76570E7DAD0C237F30B15B68A590B5BC9697A257A7F7EA1006E6D266E3754859E3795529DF707AF3617E0A47399AE2DB893FF654E1253277FC916C5FFAB6111CDBFEE42BE653FAB9B78EDBA81BD1F48A9203788E42D1BEB781B84292D84455D1D17611E6D910C1389EED1588D9EAEA076ED82F2151714C92D7C04F94AC6FC18146CA1D3F994CC7AB79DA78175FB9DADE105FFB7AB95A2054286EF4C678568C78461AB5D51B4417F787C8DFB3ABC1E8A3CF0AD326DCC7AB3EE029463C9FBC16EFDD9017813901A39ECAC0C74E271B71E42660BF576A264245B3F4377D43C9098D14931988DD6B6823362A524DA3F8A0D6AA52D7D1558FB31536876B8E507E34E01F7AC9BA1743A8DCB91E2D46D1886067EDACE62F948771B226DA87F5FC43CEA2E8290108C3B5BBF64B83285E79295D88A1F304A380BAC17300FB2FD64E1FE0CE92BE4CB18715E9FC0EEB2EFFDA222433188E99B05CEFD251F92CBDF22E35C7EDF719ED0D6BE20D6C0EA79589CB07B0437AEDF524D14BAF5CE226292D40B24F01CB97C7712832F9729F02DEBA2C6FC6C0A226DD6D6CAFE160682713ADBB2E18FE4F8906C6F8B768A88B58AA4259142AED2333AE73650E773BEC40015B91171B1B4BF9B8C68686C647BDFC2B4AA6596AF36D882FC3464D6DD6FEB6ADD5BF224ACCAF68D2E341BE4F041FF35528F85373C71167B13AD821678839FA87F83B69C43DFCE83C4CAF2363519BE2624D4E5842393EFF18C8037383A84E2231B6D8F27B045B05DCF0EB63ABE8BF5EBFA3D338B22261D067A93A3788DFAA3EA2E7E0AEFDABF5688CCD0CCD0CD91A99CC73FE6AC204988E24A3B04833083D8AAFCAE69DB47846B1CE94908CDC97938DB809BD048C42A7C658F79A1934683252CCC8BCC788E65B6D4193D146DE58C0B34DFF1C76B4FE156845B0B813FE2D236FA51F75C464985542B9ACBE0028DF379158CA32475A832BD2CCDF52C3062B373A8F1886BC03AB1A094DD4B6F27E7963D71503922CE66A690501DEE9BD3367CC60FD3E30978829A3984400CE1AE34EEF8CD9EC26A0156E18A178835C6832154195F1472B7F22741067B06F04977491B80CB2C5860F0E378BF71A9AE4B4A0E740FD06E960762AAE6D40029E471A4079837A27733314C53A43FF2D09C81CEAFE05B9C8C503F854AC91A08D2E69F30945FE450867D1838A593A118163576A28303DF9B1B530BE2CB3B00F56C38F4B62E3C3289C6AB4C1BDFE060318CC46CFDB5CACAFF5619000C9FDD8922D513366BEBBA2A4CD70DE94582FE2FCF63EDB67AFB3289F1ADE014A195CDEB1E8567B2B68FA7CF291DE2B654DA293C98F6153E68037FC5071BF0638FAF5E4F840ABB09884238973DB688602C293D9F34D93996FBD26757C352E58DB8BDD9611AF68206B58C6F051C8705C63A7D84DB01D67CBCAF2475464A6A2627F7CC9FD0DA332C5B3E94E22497DC844432857CC5897F887585AD4F31FE8589766FF04B0727331E6083B806358790AE1F73B7047E5A7841A20693B384885CC142AD514C525256BE613C81922C38649DB4D8549E36A1480A56098BB86BAF4D2DBAF5B822624B0F8971D96C9605176997D8E5BBF1A50B35002A949FEAD7DDA87F829357FAA35839D66F45BBF9D8E8037F7EC7CEFC5A18D3ACFCFA94473A78DE0BF2001A7DA4183F150AD0D83C818FF5209EA012ABB739F60DB45A475962260BDD0B104C571FF651B3C1F11A8A08063F24539FCD1579DAAC2A6DF8BA36B6DC901FF6AAA05763A10334ADF0385E56C949B1B206ABFBF60262FAB9102B05C28D29C8A19AF52CF3C0666C324AF9B1F2A113F06D7604992431034279DAF7753FA6773CFE21D73B9E92A71EF550CC87AB3605FE7814973B70D8CE3CAC6F6EE863FB281EDC96577EBF427359A2D830E6ADFD29D0D88B3A35000DCEC23F09E37F6A7AFBDA97DD8330204EBAAF12D7171A9F69E8FD6C892880BF6B4DD8ECAE16B5A5D8A7A199200C96C845E979332EB08CC1FA5E47BB51E37B997167ADB099CFA2F5D29DB3E9EB3B5108F077A9FB201746569D8739F572E393B2540CE575EDC8B4C6F63370EDF14C2358EA5C4B093D0E0772CECA542DF9C788BA436D257E27531715DD6A51AF22FAF0106700C6AA25B7C7F70B246C1A0B1F1DD0E52FAA3F6CB399BA5EB3C2E2ECB93839359980000E4774E93436950CEB9A63D50D9456D2C7ABB517904BAB1AC82DFC3DF59A368F326C206EA092B7B0082446391CBD569B27B2045D8CB3A893F585DD6C388D8F42FA956D0D58184FA0C49524FB3FB5DE394EE84D8C8E43111C101B5AD062C1B32E4C64A7CF291DE2B654DA293C98F6153E68036872A5B756D2C33E7C7648B0968A4B75C0EA79589CB07B0437AEDF524D14BAF52E4E8E86F5EEA7E42585F3B0454043EE82DB3B526DA6C9086CA46442AA138D33B5134B996B001789553E8884B19AA1B002E84A5AA060C9F3067FDA1C4F7BDCC0393B19646FC6FDF78F92E9C9A297E196BD85CABE3173FCA65B31925C0C243FA2C1AB833B969E351C113114E5AEC7982B89F742F9DDFFF15846D8E44E4648BED04F14C6DC450E8D9B88147E78BFD30F800C9340A2D88138AAB98F9A40EFC416D19B4AB5C66E214C23A74331E3FB2D2F2856ABD0D8FFDFAEC9992B63BACFA0748BC804FA53CB9BE97C9D3B9359A159A1EED0E4DBEAB5409E58E29F1DD3F317CBE28A7615C7DA896DC451E665826D72BAA27532D536869DF2F45B6A1B93A7CDBDA65E2F214AF4C1A8C9B25AC39F4E2F4853E892E7A4F0D809064795567CB2E5DBCCB3FB0DCC82525FB3776CDB6132A2EC199AA70D2C558AAE430C3EA1DFF8F09BEE865E5ABF07563C85686B2A0C1A8339620E729CDCDE0A844B547C703BE49E58A0154E00664F661D9C3612B81C429F813E76A8A0486D27CC7EAC0E6946979E9402B2B073F873FA0C7BA888BA197636D87C4C7D4741FD68FAD1CD265EE3E89F32C0DB015701A09068F04BD0505C58EE239217A33414E568A610D2D4AC946BD4AEB5453F958F832284D359AAFF3D6F39C788E78D4A9664A0F4D79F5AFEC0610ADA27E26E348FF3A480F16C1BFB74B3C41F825075C8FD9A15796E0033893A586582CE11A6392FF8581A3E5C6D7EF6E9DB08833A043AC0179AECC2505242C84DAAA4AB5C7B4CFAC3E17EC0FBC234E07824AA7333CE7988DE6CB3EDD47CF06FBD9D4264A57D5E4F0CEE8E0747EDB5D18463E1FDBDA91C1D938FBD135B898D1AA3B7E49A2D6BEA6D0DEA07BD614AB017B023798C560F6335316D580E3F5CD95610A0C0E40256D779B3761E4C2DB2422CEAD6B6D7F068BC077CF2E7EF42C6DE30BBE493903BEAE8D8020FCDA5ECAFFB23D956FEEDA8F90F22A17D68706FFE5FFA975865A596D21792FF7C5622CCC88C2EA0BE56B3DF069731B22C9116DA6A9D75AA8CA50EA84F41E8DBC5757D262C8B3FD0F741CEEFB3CD3FF9E0F1B2834C91ED3D15A5B9DAAE04502130C16A67018A6248B37DE47ED0282E1C7133C4D2E626F27A2827A93CBCE1165DD40EF6A5A26E373599D8DFE2C3F775CA41A279D23CBDE07D697DD52462D2C1878FFF629CFBE70051D6846C78ADF01716BB691DEB014361FA9DC313301BE423F410A9BB92455EA8B20485147D2A3C365F51B1186419FD93D6F533A2474B12B829320C5F150A0A9078D9FACEA7CF291DE2B654DA293C98F6153E680375ACCAAE2BD4315F4C6FCE216D4BD6FA8AE38F0A188A6AB7A85CA96A8C17DBB2D97006C47FF07C9EE493BCDFE9D6819F8269696B470AE1CF022E5FFF6241FB55C0EA79589CB07B0437AEDF524D14BAF5F22E864B47782819500AC78EC26597135BB583190F189109338A27D0055791A0DEA5D8261F9A9C26C7DF1F7C02D3B8DC03D4FA67A81C880EBCD8318B37C52198D048BD45A8752310D42229E002EAF0F5C0EA12CC647B10403890D06BB4B47699E3964AD473FE9A0D5C20EE43F6C5C96C10A160DD7C97BB3701FBE3DA9EEFFCF0A510A7FF543A110CADECF6AECF5226134F2807AB2607799395CB4CDB670A3F1F487AF2CE4CA3F0B8EA4D3CFCD65729436C1F24A4344C7D0C1713C0B5529322880AEC64FFB4E3A8B1BD1EA28448571D7F603D0AC30A62910F8005BCD5BC29389DFF962925A666C3DD3D5A05206C251693A6B34BAFAFAAFE8A0BF96FEF695480E9AA332F6ED7F5D0EFB6016F0B593F0EDA2B066FC8AE05E37AB549335A999A26A6976588E3531355AF21A831E9DC31D12805C28D29C8A19AF52CF3C0666C324AF9F6A1CF5650D72BC9A883E7ECD3CB2DF771FD39AF6231B388F0F85966FB60679641FF35528F85373C71167B13AD8216781C3A081649A1E1D792766F30AABEC2BB335EE6A610585CF074CCD43F7808EB0304BD91D2E08EEF33345845CC663BDEDE97159CCC8FC5BDFDE3CA339EA2BEE2850457595E9BA24D7ED422735137F568BCE1B7E6F16D0F94AFB195AD43F1951920001609DBCAB43F4DB6CBB10CDE443018EE611A2BC475BF8AF96684AAB99D24E03E8209EA0E064526FBE616C8C527390E48C81DC2354C7DDE3CD9673EBE57089706E70D3B1EA3F642D83A4FB1A5DC356801B86DC75C24EE218EB2D3ABDF645DDAA1424777EE01052B997ED1D38F2A55FC269E565E8F2FDB674E3F508795584BC599BA5EB3C2E2ECB93839359980000E4774E93436950CEB9A63D50D9456D2C7ABB517904BAB1AC82DFC3DF59A368F326C206EA092B7B0082446391CBD569B27B2556899FC3E8B23080B9F1B1315B1B95A6E27F970072EE89FF3CA4D257B1AAFED3B610410B441BF7DD4F95FCB5B364673281F5AA47781636D39A82A4D8141F90C206E149C0DA5A64C48C3D3248F289C798B7EAB6FDE3015E7E28CA8C44DC89C2F23380057E3403D1300D4E7E8E38545449D10BF0C51E3349AE060081BE4F8D0FDBD0F1924678D037AC5F8AC2EC2576ECEC0EA79589CB07B0437AEDF524D14BAF580AB402C591CA94B316A5D209A6508D2097DC23581CDFA72EA11715CF62460D2D44017D8F04DB3BF574B1B84D4CD5606F12F8D3D1B510C28F8788951B52BC8252E072C363FDD7501072B469952067E65B6795052B572F5600E60CD4CEBAEF82A3914A2E06BE2687EE90D6EF094CE7145BAF8DD868805957C029495953816A29BF7B90DA9FC027927A6505257C3E56293CB587BC4BD594EA26668C06FEB66267633CE7988DE6CB3EDD47CF06FBD9D426479495D471A32AD1AFADC22D5BACD44477591D872D394BE10DC917FF63FF3CC3F5B41EA00EDFF64C150C7531F5634F1360CBCD6BC1611E2CE07C987FED0DE1D454E871BD31E6AF9849779CBB330D871CE21448D2A59F2ACE7EA9548CA988B301D3343B2107D777E332B8ED8BD043D8808010686D809368529AD43586963474551A8999261698C57513E637B5E6EFDABCE21FC7257C6079DF692170E0065674323F710E763EE3A89423B6E0204514440C1434C196A670C732FF338328FF27E712305C28D29C8A19AF52CF3C0666C324AF9EB2E3F88B7413C33F736278C74D89B3C4CFCD8FCEE0DD7AAAE06C3F0AFB7775BE190FA4FBCBB19FD1484602AFEBA5972C38E8B132588FCD6BFB8CB7B8E67F8CD6E9747CB7AD4FF463C6CAB9C3D9AD1A467E88BDFBAE0B4F29F6BBC1861986E0C69181B1086D21429466DE1593B293FAB41EA8E892D050A3878B679562A2FF4C4B48F7AB792C504BA921893AA271F7780657D9141C04C46DB34A34BFA4C47F1F53EBAF8746BC1FCCFFB43F0616ADD0383DC3A6E8B770DFD7CBBA538BCD210914CEB2E799163E163C6A7D79FBAD027291C14C0D5C2ED3D5699C1EA5344DD3A56E64508927480B25B4D36D1ADE3E08B0E5E41FF35528F85373C71167B13AD8216782DE60F6E81CD5E10D3D279E87B8EF46A36B6DC901FF6AAA05763A10334ADF038DDB6C968FC3CEC9BC9CBB9A6F3B2F097906E179EB4FDFD328EDA28B47FCF14E4CA3C8BF264AD455A817857CC7136A0E4518270B935D52B6AB3EE5CE7593CFA4AE1F9E274B9C918F2A9FBD323E83F7A8B0C9340A2D88138AAB98F9A40EFC416D1F37977067C59B4ADD60C2D4343A6DF95DDA0E83B40CED0D291D073D53DDE5B5BB48BFCF8D3A53ABB3FBB27B19D711A547DB695A2B3576C9129C9A29219E8535B5DDF3A71F1B30AB7C933219AC3E9F9263B083A12CD055F55F9B54FDBFF3272AC1B36CC7B3C67DA8A559E42E59D9F92A443AA39F890F6704590130442378F82919DDE5DE7C7AAB44DE9B4E3F5A57B31CBC19C95BC788EA483D88A87B7A0365A49AFEAF09B249945E02557FED97996FBBDAC3FBB12E58FDC2B770756BD0D34466904F612918E104478A44FA5830D4D8D4E8014F570B78B86506571095A78ECE65E60DEADAA9954354B17693D82E87CD6D232A71165A471703EB3DD25285BCC83FE651684DD5ECCDBEA7B530ED7763A68D9008BA197AF7F2061F88E4B30AE4313D735102ABA1C46D78202A0FDB667E0030E75EB6491F5EB653ED8758F003A915C896CA393E0E89C2BD1C4A16615C13F399B90B0EF15B26D742D5A8D9D3C2E5C77A1C5473858B50B0AF63F51DDB1A0C332DFACB228275DEFD66C1DACACCE720ABB62BA538C7FF8C32892939ABF9C659EAEEDE9F6A7053444F4966AE58910458DAF509D2527E3CCF57906FC8AF79561DCCE0721FC7257C6079DF692170E0065674323151C0D90564EBB08D471152227280A72BEE1237DCB03FB5A1DE7C1005789F56593D23AF9467EB995630A2590DF26B7F6B4620A03DFB1328E73FFACFC1DC96592C0EA79589CB07B0437AEDF524D14BAF5F3CFBD702B465312D1385A50893132EC5F609D7A6E3406D1460606A6FAA8E62A38E46BAB9F0645F70447212E94AD982B8512C0682EE2EB6C8AF927CBF3E4FAFB5C582D1D0AC354928FAFF8CFC4A8557474DC19A842D1CAC1A70E5211488813C44A69F14277C3780FD8CBA3636B8DB30B89256CC5F519746BC7D78F7A3712D413D5C9B1C49C1BF7D657A4727AA51C3FA2DCBA2A665EE752EA78C9780925A06A0DD5C9B1C49C1BF7D657A4727AA51C3FA2D6A8225E2D5F3BB74DBBD7EBCAC7D2017E90D85B3C77C0FCC49FE301727799C503D4FA67A81C880EBCD8318B37C521989E084A2A7AA1ED67B4D5B002028E786807A54FD7F2034514A0C3E601335FC3BE39F1F093355C1EBF82539386158134659753E1704E464B4C4DCC79646664FE8E7E0F7FB6D72FFB97550E301A5B2B83928151EA935C11E8CA3A19BDD6BDD8F5C547548D7EDFDDDD7A0985C0083B46010005C28D29C8A19AF52CF3C0666C324AF9AEBE964003215D9B42BBA0235C008E83AAB3017060DA4D3869E70B6F13A4921C52E734C5E0532CC5CC9E4F37F2439E94C13A9942AB30E124CB2406182332A7944BF181CE62614AD5C88B64693131FA91AC587D400978887B1B94DF79F580DAEE39BCB505DF889E8FCDD5156A0BD29FC605C28D29C8A19AF52CF3C0666C324AF9801A6A9362FBF4B57F8929CB0965044A5E812B96D9B5B313ED44171F241A61C04E909771F2A1F84176DDEE101718233A95C0B73D71A39452816FCCD452BC6C4CE601A2CB72C1B7CCF748EC4D882E64A817D729A8A9C8E792CA61A83DABE3CA321E38D1611DB9E0035EDB1C7E7BA812E9E326388BEB807A41ED24A1E06EE33A593B643FD5B2B881BFC21AED48BEB3A8BA15053C7EB28CC4011D4CF66CD8A81B5039EA667BCDF93E8079741F5BF4EDFCCDFF6AB481CB5CBA2601A9A1F172D022D1AF8CD20DC7090EA4852F04E4C282828731E93D4068B8D85621C75C35C27081EA1EE50ED98BB7EFD8E9B7E2072F7E1E4581C33530F536AE0482D898FB005200ED602AE6E6460103BB2FD2999A5738D209FAF98C72961D5F873F8A4634BB1F3BAD24104435C96AACE15780099B6642F3D511CA9064D021FF37C4F90EF5CF75762DEA546B7762117FBAB99E2A92ABE34711FFFC9EE1183059EBEA0A45FCD91681CEE77006425DB8F2F2F499C6840C8D431E4F417E03F6602689BCC51B685C4C8E5BD3BB00D2379EED5B016E970203105654B5A5D8A7A199200C96C845E979332EB05894B4AB36C89E3BF0FED36F97A7A55B44C3E11E54CF6BB7F95C4020076E991B9478175E22A6EE6B67AF3E8291E303DE2C5C93FBC9FA0566623557A2B41FAFBA18AF9A5FB463C9E9C9A70BD7FB0BD16E5B103A734B7BF28BEB0A14A589BD3192C175E5B509EDC382FEF3A6A99302D0DAE3FA1DD5B49E837DCB1826EC9921A19B16CC76876C08296B4EB21E2DDBF49BC0B2A20A027C3C69994ABD2361200FFA8CCFB6A8C6643EEFB73FA2A24F4319FE9205EB689B285F77A25B7946572A4E9C9F09CB871AC2FB4527E3B7B8158C5AA8B997D6CD152BF45A3315C3C2A524865BBCE0542A5CE1DD6A71B1D08F448E5BF4CB920B64CA874FDF1FED718ABF65FFB008436053D1E9B0AD97001EBAE0B87E86AEF14DD5F9AC13F20B0CB2C4F50F7EC22116DE98C45BCE676AF3D6D026B03B39681CB92E94ABD921F99E71BD2BEC222154052A3BD454B5C92C39285F915649A3EA817735AB9ECDA654C49DF5EEA9084B30BE9F3D2D2513D0209C0498BC89D4AD116312D4B446DB811E0239C2ABC783B8FA00FB26A635FF754B76B1C2679862851743E2E5BF86CD44061D5958E05467AD6E4DA3BABC8754A5FAFD26BB892F3CAD2D5540F908C8DBE46737EAFAFE49D195F60CEFFCABEBF4380285B21CC44241D38CA1F3C5BEF4CF3FA66DF25C5EF5CC67737E14366134D0DD9631DF2C5B245E1017EDD0DC8646A873ED364E2404A40EE35DBD1A1FB03093DF6C1D47442F0C5F47518869EEEBD1555A52660E18D06BC7A66EE62A83735EB75A503E0A612504FCCA9A5DEFFFE51F0764EFDB4636D7FCD9B7A3F7408C8F5C974DED30DC7B447D1EC863A218F1FCD54F6DE7339705260205F979650AC27241C4D98DBE075497A204AF9EA62CDC5562E768BDCBA0665F77B1FC3E5F7D9680A5979110B65453E0E5D773B0E6E5200A6636F2E59778403DCBAB7BC43A0F3CDBFE6A21ED6EB5DC617C55FD4819A2EB7C5D7E99D4613F918535DE881E38C7DCA21FD3E84AD5734EC91D72FCB9E9001641089E6274FAAE7806E68E3A86A1C8A5F29540ECA3521A9D3D11AE42B3EF3A67E951A85893F578B8203F555DC683BAC144574E5A9B0B09F7ED0282E1C7133C4D2E626F27A2827A9327BB42185E5330D4D6A22FA30B17313B2B636BD505BA703F3A43F1225D49ED941FF35528F85373C71167B13AD821678AFA0B5A629A0C6F7EE91A057375360ABC0EA79589CB07B0437AEDF524D14BAF53CC11A9D3763AB0ACD845EE72CA3E7418E252CE748F4D11DB71F3283707522C113D2B9B030BCE6E5060EEC5BECE25EFB1E217DE1D2FBA5C925A36C11A45A39264D828C04AB8D65F478CD4DDD9A1B99905456DF0FB6842B1E33FDACF1162402076D62551DE6477CFDEFA748F54F49B6C58A0A8B7A925B9F6D2EDCA5F70CCA9446694F4F2A70CE82075B89078AE10E3083622D9EC658712AB9F8F98EE0919783C121FC7257C6079DF692170E0065674323130AFEA5E8DC8C4B3119B319A83E817B85F756DBBF3E3FDB925C2628F2294D38FBA107752E8609C83B3BB3A67E77A769B56F17EA3D468E0BC78A7D47B82C676C05C28D29C8A19AF52CF3C0666C324AF99C5BCB71071114010CE5500B358BF4CFC0EA79589CB07B0437AEDF524D14BAF5D602520B5C3CEFEBED377C19F7C2AF3B13CDB7A1959747F253545FC81C19CC327FBADC0C930ACE112A5173B116D438CE66248B7DDB757E7A1792787F77357CE3046EB305F533ECD50C813AE29E2608A748C81DC2354C7DDE3CD9673EBE570897493CF9E38A4E3DE62AB18B1A692FC19A24067C1CDE5F420437CEE20C18CF40E18CEB5957C2F46F11AE115A92C708BCAD15DBCB43D375A62B25532434C9CB797207455BA4517EB8A4254F2B2A0C54F8CEC8BFEE2036E9B1CBA72037B8AB699BB72BD4D322123D437B2A4C5341A9ED7B89EC91D72FCB9E9001641089E6274FAAE7206E61EA76C697795B53E14D1830F0EADD8F4A924BDEBE254DD7288F66C43BE7BC76F1471096AD3AA6980CBD2B0154E146C990CA0B52C562AD7CA21AD936BD5A32348CFB29058CBFEA91C9BAAA09B54334A9D2206858A323EE752BA209BF075E1BE9E92DD43DA126704227AD6C8ACEC9C07D0167CC59994D73253E78BC50327EE2383A0D49B7CE1810102876625151FCFF0C4B8263FC912299D0593B924639F4ADF3F280A832B20B79BE51F51781010C833E21F464BF3C84CD5B8AA17B0DB6846F92E92013193A7192776D562A15740FF046B622351C2FD5FB1ED9C3A84AB4F49C9DF4A3E47947E36464863DBCE729586EBBA0DAE7282DE6459936D55336BD0110E5EBAB11167188A455736035747A94792F41582B1A13DBF325CE1451C30DF141FF35528F85373C71167B13AD821678773B0B220363D11B26EC7FF0CA206252BDCF073ADF9C1F7C69BF5E2CF9D088E147AC62094699DDB977F08722CC1D1A471064B1FDF47E1B6B15F1289ABA62F62057D87A0998745AFF3D9AD7C6A05605D3DE39E5FAE2BB95A3C84943A78945B855168E68CFC94B64A7EB1B698B3CFFF5DEA189FAACB6CCDA183D4DE30F4094CEF3582126877B4DE65BFAC092CC12B2BAEDB2C31D10703E570AFBE62578528A27859C7DE619BDF17733F7A80FD26D9861621EB27FA30B79A7F66B146F3090B4F42E8E65C181182E4C57E7DE6A6979158016C933A7A8BC571FDB93463510B0295DC9D633FCDCC6639DD8C1B60837CFFCB39916D0D7F23CB8FC26E2DC26FDC34572154C932B56BE7C884321BE1D37852064E1DC863053C0D1247C3AB4633D7D51A1DE50CB505AC71D99C1D57B2437FCE495BA0A078CE9F9CAFE2E946A2BAB340A1C5B1591C199D28D761CD11803413555796599BAC31C61E20732898D50C2A1F4A818B79DA78175FB9DADE105FFB7AB95A2059DDC4ABAD841EC39B5C80AD70F43515BD9756F809DB3CFEF7E0F85F0D50D2B54DC9A1149C68DB091A5F5B6B8F4F8CDDBC2EE58A460D826E8032AB03360C03C21F10D3BAACC2F83C4DA443D6D6FEDCF2D95391FCF84C681E5342E974FA0824112B122182B86062A7239E2CA146FD1D0887EC0236A96EAFA216962E780AA905967E1F72A485661B990DA62CD535E64E6B17176DEF76C248B1DDF33A991D7927E62348CDE86AD987CA06D9D87110CDCCB3108D374DCD493C4D25B060E21B6353B561A6C970543D9DDBF94C3225E91C11AE157E502C3DF2D4E693B54D0F99C8F11EEEDE8B6DC427EEF408C0B35C8D6A48B1366F1D54BC29AFDA8296AD7B828C3813496CB0A7C094F05FC1EC5B0D4789D4917CBB0518571533B17C89D4D501B7DB15ADEC2099E66CCC7290B7676DBC08435F622C1518289042663C95E83099DFB0AEBD2A094759CFA6B924E9645F407AF56D95F0168522F92379D4A235D9274B128D5D20BEA2E33AA199A26BE33692438F35AE3E4887596A7B21A4F46286E5F94F4A829450014225B9D5B18536A8042D3EB9FDEC68EC2177001A10DCDC94D1D047F4138E9ECE19F179BC105FE39A4DBE86B4564878A04083C82C5B91181540A0AE1DCFB1B92289D8AC15FBB504360E6136FD7924242964139BB14D59D25A0B999930E0D30990D98376ECF101E3510E2DD605A64A7301804DDB1454D479D208A4D5929F311FDA8D7E8F0A38FCE7AC22AA98524138EEBFD64049F667EC1404388EFD6F760862C71EB223A18634BBB0D3147254041C640F1037FC5EE323B8F9C6BA18C16D7A1267C6D9DF871F377DF4A8783D3FB3519A06E0467A9FEBF999122E7693B82015B9A915EAC60C4A4F5D8112EF27C3AC9DF4AF759AD04E0ACFC3F9D793634F295391FCF84C681E5342E974FA0824112F709FAE6142DA20DD0AF802C36A45FF0CFEE0D0C299526927E2569D98EA2FC6D5F0168522F92379D4A235D9274B128D5D20BEA2E33AA199A26BE33692438F35AE3E4887596A7B21A4F46286E5F94F4A8E01FB5F41E32ACFA14B1AF7263FC1E172BE960574941FE14256E0748B0C6EB49D21AD9286E1A610C27677305D31B34252016F50620496A77111828928368584361FF012011CC89EEEF5A47D58144A524665A9DFECB48F654E8B8CB66C0F9323B8B396BC7B0C10ED0FCFEC94883A6F0072F2E6ACD78A2BDAAAD627DFCE7CC78AF457DC2CD01884CEA34DAF8F95D67665AF1D899A3E0B2616ADDCEEF8D29307CD057A6DF8E43779824CBAB01AD16FD96F5B1EF471D2FB5C53388F5951A07E0C18A3251394491DEE06996C196DF89A50B459B9C7587381A2CBFA766156A174736DBF2BA82DBDF197C6AF6BEC5D28ECE2EBDA283E5429EBD694D5CB787BD47D42F6AD3145F0D50F7617D77AFB8035AE4953E35CC60AFA48D9F06088912135461AE8CD43012DD69F11637827590E2125B808AE5E458F1475C71406F28D5428A648824B9547B082C0BCFDF2D157289B32078D39CCBACEB8F28D3430FC5C9ACA1926AD60737595D7AA2F30B59C790F2C3114BCF7E2E6DEAECA3C502FBF573DFC856F3DE8423F21CAC9285172F85A6F44FD75529A8DF30E57BF156B9C4B7AC614438A312886E8AF5A63B297F390D5B217903B24DCF15FCA0E9BEE5766791688315522AB6F11C7B947B8F6F8670C05D2635C31C9635C7891C322ED398C0FFE0D2344E06280AF0A0FE97DC1A63021722B5D4D5A6365F0D0733E3CF94E5784561C9708FA804F588322031662A1D993FBD2B7CB0F2CF7FF6BA1C4D0C86EF58D66912C617139AA44ADA01E266EDB2C8B9D0A25643A5F526413FAB629DF09AAFC836A2FD56227428F2E7085188F8962CF391E4CD265523D6E89D4F131DC43A5212CBF58B0A80BF65D84FE5D9759862C753E63356EAEDB2676A8470F61040C40B5E6BBCA6F01FBE0851A892C409ADFAD3097B6F7F631F84B1A006400F30AE24D888468A9867BCD3E4C07D51BEDB6A52F5B86F054F60DF061BC63C43BA6176E4A5B02E6E669D46189404B709C2D37D4D92213149E02A3B285B29E41D5CE24ACA35CBA3E93831A6E75104374369AFF531C4B5B7405E711EFFFCEADCE1F1CCA5C7AD3E4CC89D2581CE12907EB337AD8CE4E54CB222C89C20F539F1161485793B5807B441045BA843C007FBD664A153E764C7DC242448719B2BB202D98A180302D1B083DC08E12C94C7AF80A13D0ACC2F98260408651DF7239F286D5C5ACDA1A5EBF78F016A5A7221F226561971E33A5F20556D04E41354024427146B00281B54223491855304A4AC1173999CB9E8818BCB8EE4E2D9DEAA51E495EF44AAC1637A6B45D199B5C9A45EAB8B83C4B374BD432BEAA545ECD974971F12304DBBC1C8823164996F030AF245BAD586C958657ECEA362BBA51C384D99E3B43F24AD84697F965D0E5EFB22AAF36241C7773724DAC4CDB77F4E6C87D2386D6DFFC552DA47A0FB32F5342BC4A0294AA9066E291451F6D7A6CC428BDABE898428A29223AD003EEB642978AAB9D8DE9808970B442121831D04356C3161E8251B13BD6F6D0ED50E2440C7A59B3FAE513B6FA16D7345E17FAAF1A381D0ED1A7754BDED1F58EDE6989E7F9DA13B8CA136C50BD36638B3C3BBAA81F883885F5449E3D595B9CB309D5D607C37A91D26B09884104443917ABE1C8255DD34A77FAA3B746C038EAB5FD3C5499836A35D7D1550666E02CC4D9317680854094E107C71D961E2586F64C1599B2026C0C67C9DDF38B6CF5D4E6FA8A381F652743316BAE79062E2380DC916B7F0496A4F67A9655E7A7290D3296E619B14B370291B7A2AB2B3295260205F979650AC27241C4D98DBE075497A204AF9EA62CDC5562E768BDCBA06FA1803CC024FF9295EB3A7DA79B4F0ED83466F8CECCBB40621708BA729FE75376A7B53C2B1E001E3BE5047DC553B7405DA146FB10ACFC73697C9C4C7018A19583B1557093DD466B8AAF1F8B5058165779EAEA59BE175C862B83B87264990C039A3B77D8B19E3A6CC22C70087E90C1ADB3B51B1664870371DC8207A3E155B1836E626F6BD4395121CEE9D11BD9160BF221F80BA0C6F0DA424022893A1B583C7088C0B261CA36E37B40B84540B4DFC25E55D8C2E8C6E03B5D487CF09662503394EB700FAA44529B9C30E9419A2E26BD6B2E676A36A9A8EA37E580F95CCD4A38B4E651CE9690794F463913732718B569A8501B35FC0E90CDCCE1724507AD13D5ED7F07CC41D1BEFD1598FDDCC83F37980544E360A3FF34F0B08CA1184B3FF5219A04C43E9B68782F9594758F49A6F3D342B0D812C1B13A620343F15D9ACE0022E33BA499744DA27F277F914D56DE45698A741FF35528F85373C71167B13AD82167834B08BF720F2414C19F67E427EBD2D4D14CC2ACB24F7F5F8FE32B35982FC5E43030188027E824EA2910708DECAA47ECFAED42413FEA5137E8257CC0D4E949B116C89784C4BC37F5B02614941CED6639676541AF4DDF436980BB7693C813E6A9C44D6FBDC48E2B9A40AF1EE67463180D4705709E78F7FE799EF00ADAD414F83FA3BCF391E82F3C26B90520C4DA669ABF7DFBFEA315006F450397CFAE72EB9BD2B41FF35528F85373C71167B13AD821678F3E62A2C6306C92EFF436518FEB2B887130AFEA5E8DC8C4B3119B319A83E817BC1AB833B969E351C113114E5AEC7982B45FA2222959403E2B2FD6BDD4A56D2A4E9568BC1830E91577F2683A424773DA230505E197890167509F51FEAC10D63A3DE33CE61E2834CCDE976EA39B9C9CEF30751FDD33271D05743FEFC045A975D0205C28D29C8A19AF52CF3C0666C324AF9606C3600C5BA9C05735C636212AE00EE05C28D29C8A19AF52CF3C0666C324AF976C444D691CC6363DF8F5E1ACC4DEB90C3C84BB5C3DA8054A0CDC1CAA68614ACDE33CE61E2834CCDE976EA39B9C9CEF3F6D0C7D315C24F7007700992215EE31C0E5FD4E6C8B7DC718A3F26D468931CB9EDA4202C51A8100878F0259D6E78D6370C9340A2D88138AAB98F9A40EFC416D165A9099F3D8C2E642328B84175E18524DB2F5136BDFC63A5C442B4EB71D67074DA31D80A6AEB5A00155C73FAB3B374888A08063F24539FCD1579DAAC2A6DF8BA36B6DC901FF6AAA05763A10334ADF038EFD40ECBE72A1BFB9CE8AA8774DD4B1F21E2F1B6CB1966010B97E2265B473A29B38D3406B97830B6FCD9410DC3FBF7BE63937B0129B949454EE9EBEC761CF05ECE5C9A603709C2BBC9561D22AAB0827C5C800BF685ACAB3A15FF9EF4627B5A045FFE3C7A552B8FE7458E4D4A55F66F531686B69A0E65F120FFBAF1D63A65619DCBEAC05C344A9770422194F87CB362906887515FB87A9CA56CD78E1D860C8E5C49DC50567382E2AFDF9D9F2698FEAD057725DF33429580C2960646228417535575DE843733BFDBB31CD65842DD19DC82F1835E2BA29F02049756FB11606EE7BA393D385150A4E2A381CA50EF60E503DE0E7D3CD8AC1118872321C99BCBEDC9C1317C96F91A8437983D36E782336B61FC36AC68825B1D1DE26C17E4B98F8549E206AA207DFCF13B366F018F1975ACED82EFC606F9904B45FBE22C4483A243C2F3CC533ED020D9F2D5D8DE507E9AC031BEF72A03C4D5FADB162B4BC0D0348CB30CA16AAC4A7E287D7C407373AC0FD88B66C6E0FDE0B9BE374900FDCB68DC218F755659A7038813EED7479A1FE0337BF067EDDED5D58FC3F762650B152499C57499447F4B494815F722116584213F98D4846D7E934B259916E66453C3CE956B7D9DCA92879312BEEEB5BDA5A45E9F7444250EBD8982591D5CD660E22D5F46972CC19DF2799F369EF0535CA58CA18F79BAF5C60EDC77819352C12053B113AE113D95750E232C756DD91DB44FDD225C2F1DEAE14DB82FA214F3094E2B91B1AE2EF8B5F71DE619AF867CA6223135F2B596C406D22C4C626DC15300BE20052DE1E49E61204862D0814D2A7F145C778039BF3CCD6F6C5F739F073A0313C72284411D65A28A08063F24539FCD1579DAAC2A6DF8BA36B6DC901FF6AAA05763A10334ADF0385D020126A63F933CF3B92F5C797A127821FC7257C6079DF692170E0065674323A086F526DD55CBE899B1DEC4E53DC71B11A08C2726D1B3575B2278203F56348316F4CCC3EC7CF487AE61DB84F935E878B05313C3F0613C5BEE7E2E566567353A5F25648F5E15CE28B3A1B9C6E3E2996295391FCF84C681E5342E974FA0824112C4D500B99DC2C206A62CB88EB33395B774EAC744B0C62097D8D50F43FCFCFC41DE33CE61E2834CCDE976EA39B9C9CEF3EC58EB2C60384394FBD3FD23B138E8A0BA526F6F4C1964F83C03951BC8FEBB788660015823BB51255EC74DC1974A29126E9747CB7AD4FF463C6CAB9C3D9AD1A4AC74610134768DCE49DD211F29129D57B0104B4F52ECA43EC8A4E54F09894973CF7A0F958EB82E785FD669E0D0723F1A954DF1605DF2EA6EB30A9E3C7E5853AF169AA32069728E4095D817E6BA020DA2321047D5516EECB6DE17E17F47819B3D5E1B9D5B07889AD00A8CAD9F86CD5753A6D49D45FBAE46B936E892A12B162A1278D0E675578B8FCCD3762E1CC97649EE81E07CCB0E02F5743CD9454618F6244628BEB08C56DC781560F27E90641217BFF41975CDD8F88180FB6749B364D47B7BD9064B4F85F2773BBA45DC865A9D32CFA2A470527A6497EADBD968068D02FE57336FB7E8CB29DB344343255DD767E4BB846CEFBED4266EFBCED105319701EF66D1AB82ADBA18220DEF216EB52D909D7C8213BFCFE93D437F89B5CF0D4E621AD15F25648F5E15CE28B3A1B9C6E3E2996240ED516BA9AEEF92ADB29F3A7A69B70D05FD3D7D38193717FA603738A8BCA29E874BADE9CE6DB4E54DC7CBDBA5E1B390DE1AEDC5C49478E0D029291F3A98D3154F25CBF61558AF773958E31D38F11B321B7301CF4A26B6C5D30EFDE6C5FE5D89C0EA79589CB07B0437AEDF524D14BAF556005612042EFEE55F230EE97B65725F2271413966089C1BBA0304E7D6A475C3DF9A626AB43D0CEABE5945B40BAFBEC9AB26A8367BCA6FE12782EAB8DF36D3859061B9C14F3690A5186B07C0AE5D73C9080B431BEEA1D327767A180F2AA72F2A6104B2311E7A841115EB885BD0723319CA8A9A487744D6945EF812978B3A7E73A325B22744F920EA44DB0256F6DEB659A08A4CF56135622370C8A1E9381601956A4C2383D8242B3437E4765C62594E2FBF52571A07CEC204879590B7BAB7FDE405C28D29C8A19AF52CF3C0666C324AF9FD3CE85280A2D758C01B7D8CE889B8C2C5082D3F0D2E4FB1255E093D2FC7B81F692AB419C5AA1D32A030CDB7DDFCB256DA4F3A5E3D890E785195DB37FC0516B4111C47EFA76539A16E198877A26C5D3DFA000787AA7191C3311B4F1E7328B32E0D5D1406B4647450A8D69D26431D184DC3931792B68CB5F619AF5E45AB94CF3EB9B628AAE240F71D8F81942615A62618DBDCF3290826EE9B97FC3AC3B23BA5FC7961F38BED9E636873621A9FFB90A50784AD1CEE38CFFCB9AAD3E6F7BD78DC75143A5CA235CAD1106F80B91D43A669C5DC95704ED70EE462BBFD35957AFC94DEA876A3096C23A2E08DB4619B5C48DB7F3FEAC8DEBD60642424511DC26DCE6B744EAA34F4D0FFEDCB4C8A1AD244FEEF54C1AB833B969E351C113114E5AEC7982BC2AC15EDF8771A6077FCDAE3526187AF2CA7927920D77B85197B8E1D302B7BBE3E0531BD69AB22A4A19D51F7C795668FDCFFF5B5865360B6423275EEA9CD092462F87F8E1103E18228E314AAA7C3290BAE6A688DE97740003190CAF86A630BE75751EF136C99509A91A6BDAC5BD970B598876D4BB387E241CF866159815B4578F1575685BCB7722E3B87E7B934B75344599AF72259507AA1B3CCF43DD82248BBA22082958DE6E9FBF7B1A3F9D4A4058DC1AB833B969E351C113114E5AEC7982B8671DAF4A2D18DD92C974D2356C611D605C28D29C8A19AF52CF3C0666C324AF9A3D4630228F96E7B25D0ACAFF6A6ECFDB75F97F8C7A81155C2956FC44E079E545DF647E3985E9C1151D134F0E6350073E06B5A60EDFE80A70E8B1222310C7CFC1A639AE85B45F3836BB04BAB585541EB2534BE065AC456A902904463FF609EFDE674436BE5D8BA29198F3E2E9C905569D131EB3A99CBF5B66270D1FDB90B1642653E21E9863AD5BB6D94BFA52C86696A3DC10C1F9E880E5A2BF4840DD77A5BB0D4C5472495C369FE7E96358A2FD4AEE2B079A652121D68B59E09078BC05D425F704B0BFA9579F877FB82CDF89505C18E111A3E63D3FDF2060D6D6583FF6F251CA7C65AE869512237F68A70FE61FCFDF762A5478716F27529D07481C9F55C9A09C7BA845CC367D7959D4BD76341D4132C91C827DBE187AB866B6AA49C6C2882F20F328A1C2B5B06BE47B9A310CBFDDEEC5075C8FD9A15796E0033893A586582CE345C01AFBA363CA5E13C9FF0A357E0F5FC7D14E0F11CADEC794EBF788210252643A665395B5E11ED9E6096A49E6C943776BBB2B4F211FC11560C311EC44D4C2EC454266A1F9077EF38EEFA2C3F00B34B25914A671D127426AB198B310C858CCCFA621259B75DA53577AE2E9A6752348EC0EA79589CB07B0437AEDF524D14BAF55EFBEBFE72B69CE04E1C72A52D3F621CBBAE44321C30D3320A3FD5672E3B2E062BEC43AC9FE9810C1BA1790C0F0FFBECC0EA79589CB07B0437AEDF524D14BAF5F1575685BCB7722E3B87E7B934B75344E318B6BB4703C76D2723767BBAB22098AE2BE03B82A583CB6A66A8442663AEFB05C28D29C8A19AF52CF3C0666C324AF992EADA4C79EFE9BEF1273F0458E398A5E85FD04E7C7A67588A9345E8B43098FA835CECB4804B953B65800B2D34B0954D152D19F241CC50800094FABC437A7250FD2253D3129C1B32D8B45EBC7F1FADCB5F25648F5E15CE28B3A1B9C6E3E2996220200FE661CD3ABBA9891AFC80F217CDD640082B8077A1E4AEF8D023F91B5BC63F31D4D52077EF3EA6AE62786396548866B350772F6CB61A98188F869F21A144A7CF291DE2B654DA293C98F6153E6803EDA4202C51A8100878F0259D6E78D637545421AF73DF114174D1B0CDAA710C0D4671D9936E9CD93307F8F879CB2CF3C50A1A7BC177FD4D38ADF97ACB09576F2BD91EF1D4A4244F665BD0969D372749A305C28D29C8A19AF52CF3C0666C324AF9A754E6E19DDBB9F189686F1F35C34F0EA7CF291DE2B654DA293C98F6153E680311F71EC57235C517F3522784A6C0F8E1BCE10A712970838484F7BDF1C21ED3DE7CF40C8501C0585F274999EB132F9148C0EA79589CB07B0437AEDF524D14BAF5BACA99811B5E905C8C61EE4A94E212A40C19BA269A4B8F14765A30030B7892C18203F555DC683BAC144574E5A9B0B09F7ED0282E1C7133C4D2E626F27A2827A9285F8935E3588D61BA19C7C429F66A771CEC73C324FC53CC73542B5EF06719779D321F8B0DED862E02AA603521C2AC4947AEA081E2B1F68D73DBADF72DE65C97C1AB833B969E351C113114E5AEC7982BE9B96C30B931E8648050DDE9E16A53B48596249E2869DA7C56246EE74C5719C5BEEC6067020C3EC17CDC8E8953B66F6EC1AB833B969E351C113114E5AEC7982B27EA0E176BF6D98E156E907826154E5B790AB955204CEF0A527C6C705CCC7CF80C9340A2D88138AAB98F9A40EFC416D1CDDFEF3D4F3F0C82F6D09267FBD21C7B929D02085F5EC0D83A0E651C3863CCB3035D8CC452B1884E60C9C58AB79AE0537E103689FBF7184F547BECD5AD25C635FA921FAC0ACC9903B448812BBDF67DCE05C28D29C8A19AF52CF3C0666C324AF9B9EE558BCD2C3970430837EC85D734B87F95E78BF6A283BA9988B521A47A41BDD9C0EC00939DEE2574F7875B3B098A408873C10ECE16421EB807A62B13FCAE375BB74D628AECA3BD9C19C2A8D50946E8ECE0CA25A2FC51283E43C0DE5A9875BDC04E908E0C7902E6AAE0A5B0D65E5FDF1C08146E6E6AEDB3BAA00D3AC5B9DE05232FFB1AFED78C4276558BB008B6C6D9AFBFC143E524263DF4D1BB5D5777F3AF41FF35528F85373C71167B13AD821678F83137E352B0FFEF259E50E333C633E78E7385148F1AAC58BBE4F90A0C948003C3F5E82C58C968A4210D09F2CC641BD2AA332F6ED7F5D0EFB6016F0B593F0EDA42F3BC800C4A5BE02F7D79C637195077C0AC19B39F674ABFC6045E6BA6FF3ACEB3DE1BC658F2F3FD502A8FA21FB1D9425FE1AD724AEE24B5B109BEE072659D0F04DEC773F47D102E132259B565131930F80C3EE1ECB1F16D087A491490472FB5E585E1DDE753D745B4A310655470E695E816E7AB922962924F2CDB0755AEB923A4AFAA64E8BA1176C1A96C3DFE3AFAEC2E3DE96005A0EFF6A7550C4A9B19E509DD295598454DF0B0EE35C1597F8E58015142824F1862C2AAF25D8D62C94DD48231029748140F00642435198C33FDD941129186904549B4CDBBDDDED5A93AEDEA3C2BBD0E9F231ABC8F3B038ACA0BA20F839458E3498653DA238E25A10DC152360095D9A524CE121ED9C0CAC42E76B0390B22E243567E4B7CDDF1E1FBDA6036361F7DB11E6ABD76113536595937372DA9ED714F146CF900DA05140D3094A383EC13021C8409480180F61F473429A59AD961CB10FE4C1C71311C8AF77448BD550F4BA4505ACD43CE1A46D1831B22B78940F652A8D0C5DD7B9F55D0ADB8F9F77770487B016CBA338DFC8FD79B792F67F43E7B67343A19CED970E3BDB606BA72FCE627E8E47911A1BE129811EA9A958EF6952FA7D78A12DCB98FD7978991837D72A16122CE0182D22002982AE940C2022A35356C731CC5D511B6F199BC1E49F783D64879846E5301180138DF9B54285F8BF636D1F431813E6E5D3E0E7C3B63A922FE1838B26A744E21A049512F991A00A41D2ECCE85FAF34D5FD2194A54D12563A4FE31420B9C4228FA379EC22B7AF8214686A2F3B16E93BD32ADDE9DE899FFEBC494C6381F6ADF39A8C2C4F2EA000F9276D5F32D2F263BCD7C1E547C9F386DDDC6407DAA7C52F14A18C57B1F87CF0FDCA5FFBFD6E9D07BE8E82C4D75D9519824200FEC8667ABB0B63AC4D10060FE925B6000364DF0E30FB4F1FC4237FE8679807954921EB72F1BC84B5BDB65F6BF9BB7D74BA3AE6319FB682F26C3A91791DB1B1CF9F33517D61C766E41FF30DD64385DD5379BEDFA7BF0A04328513472DDF52003518676D425B9F932692150E43D5778DE2D6A54D2256C5ADF872B516C41354EFB82DBDC1812C561A499BF951FDF94A5C87B137947231B9A9543E5356CDF43BA11D78F59FEF29F4B474D859BFBF16C0ACE0D0E51F9132BBB98D0C69EE385D6E45792501B80BC6C0B01626DFF645304DA433A37D311BC70BF53E0AF1AEF81963E6A3CE7B2E4450B87B01C84B0BDD220597EE8B17DD072CD2E4FCB995CD4E6E5AE54FF80E939E6E40241DC7B93E2C118C3DDBC9045634743B298AA00862A4EB4188429659382845A813E9D4B9BFDA2D4B16D24DF0E39AF7F399F27B25F3B8612228F8B12050C844D5F2720F28CED22FA9E5161C02EF2F373CB45A1383B09E05B11DB86CF1C3B662D9D6C023EA07FE6F2C2C6946C23EC9A45A066AD3D184B8D5D500D846EDD46C8C61710B5817C576EDAC0453DA8BFDB759955DEB87E6A5F75D95AB0B43EF8F0848242966234CF315C1951E91B2C55D1EDBE3EC1419AEFE2347C59D649E14035D9899B29F14AA6085C5CFDA25BAE52F86F4D1BD4556DEA43CCDC0A944AC903F2F89A3FE4D229AE349B5509B140FEF64826092BB018CE69EB7685AF2A6A57665488FC4A5B6B5A0D61A7948FE41675E1B1EF2E090C9E162284635F3F9E412C1C846996B909917F121FE4FEE786083B60A40E74ACF84D7753B5B38E328A98203F555DC683BAC144574E5A9B0B09F7ED0282E1C7133C4D2E626F27A2827A960129571A954CBF4581E484C9D4B7540826FCD5378B557CBC1EBF7C22EB86318B3A58E460D8CEA593F35575BAA35B60EE27C6E3512E8D648B6D80ED3DB9166F4FF4AEC892B61EABFAE1527066FA081D8689C05803406FAFBC563D7B7D50344964B3A96FA3AA3DCB8986FC9FE7154242E65FA35B99852A1BFF4B4487D2ADEC6A62059891A700283696F8175F1D805F148390BA30F9A7B2EC8F0A29654E82C3EC3035A77040D192FF717D9692446F873FCC058DF1A77D1C460094501F243A53CA0457FDEB92D231B67F5BC2F348BD7BE75CBEAC05C344A9770422194F87CB36290ED3A6D5C2F793D82F9EADC940F1868AF4B5D40E4AE44F7BEFD5E8551763945A19CB734FD19C7C33F1E1E587C89CC326A9D577ED83AF8AA358F08BA8740C4A7607E6309879257BE3C28F7E455E54BAC25F2A750C4EF89370BF3D22C1C268A5658AD549EBB3D500FDB5EFB67CC1C0E0179B2A92487C83406684D110A05BA7E42B8F0670DFED89AE3175BDEDE6285A47156470C276F611DB5C5485AE19F2E5BDD0F7AE4C7D7E9B9DC1A20255D5AE205937A0C0AAD448D018590D2D73773D2B07652889446CB4110CF3BA8A67660EC52DBA3ACF77AD8CB61197FB327C50969A4BAE7E1C567E4A2E101791ED2FB4A1594DA62A2DAF059A79218BFA512E063E39B06869118CE92EB2DB978402D9840AEAAA0815F46F913F80D8ACAFE4077F09C7A86B8A9F95AFA2FA234B494F0BDBE62EB275F9118CE92EB2DB978402D9840AEAAA0817D7B82E550B2AAF97414B9371612C339D2FC624B8446E010155228FCB6F013741692C99E51783B6A4C74E9468B3D22C8532A8D2E89B718C467E54B152401E3AE3D48CCB08722394F6C3F92FA387BB30CDE566D5B0C654CAAD9094D2997D38707DBA1F34D2E86B76E665F725FDC445E7CF8E68FAE2CBA5A887993189FD5024A91BD83A679A01DF8A425CF9FE85DCD7DB3EE6FB2A067A8FDB88E937BE5269206ACBED470AC6AA8591EC72AF84EB82BA6957C509F3BC280C9D4F6E18633433BBB0EAE3C23C01FB9626BFCC0B93A45D7EA6AFE9F5EC69F089746290BCDC6B889079474DF112181B090EFB0CBAD3B5874AB76FD5D7F550A784090FAC8841D464CEE04877FAD49E75193D04DB983A954ABB64ECD8EA20C8C5B0CA47C95B79C876E52C9A63A5A6E42734CF22E3FB62F5EFBF7491C0CDE6484F537D898D95D108A4A0AF9AA3CCCD0CE01369D8E5F15757854BDA1E1C8B2F7B06D339FB38718653D352F6A9AD791A057BDBD2FACFB606CD8F1B6BBECA6E384E67956633FD30C1153715EABFD983FF6ADD0B29B311E83F05E311066FEB942A9D92DB2B6466463C4951873C5B98DDCFFF96DE3FD7E6FF153ED1107301751BA0CA9B92D66D68A4C209048AC688565EA5538EB8A850EFBB2116C3D13D4C3D44D60451BE14E6E2D47BD24F25C3C4F32E5BD830545DAAD67278E0BD151982BC25C6585181290C7CB686D101B55D4C36226021EA0B7D19D671C70150878FD9086795329C771A6B5202C76BABDD3E373939AEE46D891AC09A4885284685A90796B1E3DA316321E73B2C84BABDE10E7930322F8E5826F8C190CA0E2C26AB733D4EA70BCDCAC0CC5F3E3480BB20CBE7BCC307BDDA0201A71C4C2C8FDCECD16C33DCE3A7663DD5E7A71BD024C5507CB14AD70F9A184E23DF02E222B579A21F51D3FDD9CD220F279074BD409DC74250CFD036EDDC7CC22156BBE4E9F2A39097E2171C084AD4D8CD202A133486BA5105C162059891A700283696F8175F1D805F148710291134431D15702D6861338DD5A6E7F91702EDA2B7D88D736EA3B5CD9599A0DE6A2F200F050CF0880C9D092EFD9334BDDA3913B7D8D2E724AB88EE96B97B3C241D19091565023D5BB654E89598D61DB1B3F94DE628CF5D4CD058E8602C8B12DF0EAF355304C0DEAA4D6C34F9F2C7F5A0587E3AD957AE120B0E4C30AC434ED7E2E6DEAECA3C502FBF573DFC856F3DE2C4155681AF334978090535ED8EEF66A9979F5B7227493EB335B836B5DDB0A332D849963ADFAF82F4FEAFA747F89ED33BA7248E099E474F13ABE4F7355E3661D2FE30ED31C4FBA9C5448D026121B4733ED1304AC60F124F372971A9407A37E3CE2B9A1EEBCE1A42F9E02E0CB1BCFA2F8AA507EACA8847D09BB64B30AB86F5E7A2830A50B50AF20DBCD0370F9286B942769E51B324B3D1963163D6576740F5021BFE081309746B8CE8721265CEB9267B6A6077121FB3B38CFBB908C39C8B40A0C493BE661FD95658909AF6B825053470BB45526B10EE3245936BA4E4276A8E2A01DE832D59AEEF3D84712F4B90F0632AB5BA0652B25D49A308FB06C29AE1F3F3F7F4F3894A81E0B3CD487F68D56ED3844CD2FCC9D208E0B7CF03FB95C09DBCDB1CF7C727A6332F5D3A41C7BF7EE1D267F60FD900211B4737A7345EE80003AF8B5843882AF006A91DC9EDB22170639012F0B9FBE87408EE4EFD94E256AE44B178F00971569FA2445428616D7701F4F303A803C0DF98B6313D3A376085111AD6BE9F98965481DEBF4CDBE81A662557E462F4B8BB7B95FDA36BCBEA490DD7BEC2D8E4C2E4FF0F500B34D82849155347790A763A0262EB5C0B10288B020241255290CBC39EE01D3C8D108F59BB936BDD8F2A82DA5689157FA44BA9B6B302169EE573E66D93654419EAED3CD626905DD77F178AC394BEEDF43723F3CC60E77827AFAFC7CCD8450B6E7A680CB3E2CFFE05B7D5B5B039EC9D39405030052F78AF68972E168923302197F5C1313A29022991707EECDFD5245988934A50FD769BA2FC9C2018374ADB90888155BDA52F280D1C19ED98D0DF197EA99BF15EED8A270C8668A145C2E9B7F5B8D6D3F9E07908519CBB1F58FC0B4E00E1348F69CD4FCAB62585B43587707B28725A48EF5AD8B35ADDFBE0C2E84CEDC518D0F9A9FB24FBE68CC296CB93C5408837934DD9D492D989DCC669563DA0B757A5A0DF78C4D42DC18D76BFC35207CDBD322270493FAD01D50021678E251390A364FDF03FBE0CD9C9FEF5C161EE58854E27E51924083FC38C06C45BE0ED27345373646FF28992121329C857534D74B014352E95060B8EBD533D2F2D14C33FA2288C8286358689FD4989B089EBA04B8AB0CDD1EEBD3B477B0E39CD761F16FBBCB7CF4A9D83A73D6ADEFAC1B3CE386DB4B71E438D8E9662C0F9BB4B0AB6A132CBAF3C9B6EC08DC62C37CF2150F8A1A1283A8C40396AA935270DC868A51CC5580D5064F293B939C203AA4F82EB7C8B744F091D68223EC42584CADEC7D6B41CEC0910AC4B7D61546F4B24825AD32254F1B48EDEDCD762D9BF980BCB6E4012D8ADFFE29A6839BF18557C7FE4E5A28D3DEA7CCCCAF48246E29D3CDFACF584226AC8639318B98CFCB577B67247FB9496FE6128BF388AB5F8E4869E70110469D297C5194A32A22CD9007F6CF269EE5AEB92F1D462D72D26F9FBB4AA7FA914D5E4998614C605F3CA8D3DA86D8E4F86228A469929EC20F5CF8E82EDB8858550581942BF3BA3096107E41FB66EFF45EC3FE5708D5B2DF000530A80E72E8FAFB4DC0CB41CD2892539EBF11C7CCE918CD2529CF35A47AC3F384BF3D0ADC7CBA41725F802D3B05A145DD9D3E9E69CA69978EE47FCE294C68BD611B87AA7127565EF89A6713D583C295B3DF8D5F42C9D4E4A90EA3E7ECAEB7DC4292897ECF3A496D10B4AFBBBDD35AC46AD59CFF0ADAA99C2020A45257A87D4E4FD61061526EDD0D556CA195BB0D043D6099BC0600F5166F58849FAB80FF8E7D77B9E8E0DC8F958A07E309526C6A79F80C2779A9CE4D2EDF5A0AB0886510C5F68E01F2C736CFD8500EBD56187CDDF414C35C7E6A9AA9DB75D613AD579E18BCF416C13BA7B2526FDEDD4F0684412AC8DB5695D858162A4DED6F32102EE1E4A40D8E5BFAFF88A75623B5CC9510C4C53FAAC04850E605F4FD8DDBF81A04BC57D69613D16B83C374FC1A7EB3449A29584B6DF7A05F5F53F599B6BB05D0F96E671DC2DF943E6B031769706A92F73C2C737392341E15A3D5FF9994EFA4F20C0FB8120DA1F2659931E5264F3B961E4C5583E54EDFAF3C639F2ECF6704BD3E4D6D1EF5E822576636482C5E7C3ED6BEB67E1F1C7099DA9D14FC6431CCD1DBFFF96E1D1553D81F4C1E9F805D7D3FC67FFFFC9B1D8E3C8A6707F26590FEC1288356D053587C08DEEC0F29DCB4C7B3027D67027B5AD0A16A16371FCC0A0836FC10A386645F32EECD44E189B9F860C7C27466AF154C169D2393850BD6FB7368A6BA807A2790663255790006FBAB132476BE7351259DE171DB13C33A95F34DE9218733D2CA358CA0354E745BFDF07F1624878D5E2EC6958C430B093FBA511AF5D1599C421FCEC5624C3E6B025494CDD67328A3E7ACF189A894C81094ED0DD26131311B5E1A2DB1E7665F631AE4E9AA87540D0D03CFEC23C18FC0E8CAC8CE7C57065D1BF1DC9D1DE9B07A83227481BE92C48F37CEEF579C7F48C0536F634C64EFCB6F3801D8DC75F1C203CE49C9FE47EDF0A0ED6F5A322AF9F84CF7F89AA510B621F54C05FC30F53163D15DBB14767E4D14FBA76E28DE123041E9F5A23F9F2E705C59971F62E9B2D4D0E4C8B4552B8BEA499C0A6607D21D93CCDD540F16849039C78E5A44C55DBBA1AEAABAD700918BEB5E134C3445AB953D2585E7F5811640CB4C64FE0EB310AE6D53652D5C6F9081356E69AE9B29BA30C5E7BE59B776EE45F2D8B3FE517178F266DF5DCE2BCD4C097EE1F1B72F8808664768948E7D8426B9CE17F1B1D22A3AF0E4FA1DD768A5E641B51D0CBACFD3030585461A6ED99A3451A6E2C415CDC760E7E1A3AEE6BF0A2DEED6DE7223EE46D6B45A38B22DD5FCFD4D474322292522E3BEAF7F48F31339A4C81A21441AF438A20628FA55BC0802BD70B1700C541E357FD2F6F00961921CB0E8E9CFDC80C3E9F9EF6227D1F7A02414530BFCFEE950F2D350C7C59A0A18E77FE8A6F76A528CEBCC04A409F73263BAF858AF8A7E1A4FE63E0F14F6B22C15D4D0370C93693D12ACE67645EB17C3EE378C3F1E00B3EAA675DE35B9EC0B04352A1A672FBE52C00258464AC42275384BF9F1057876435A9276E3F736E3AEC7C19146F71BB87565F519A63EBA44FEE1CEC9673ADE2E7E5E394816798ACD2724BDFBDE93BA190B7C6D308205659C0EF3F0163AD42596C39BBF8C92BACCDA7EAD63DE7C68A072A61FCA33AB0EB533ED4A182C4B09A7EDD439C4C54F0F9D59D24C42E767A5053D7E12148ECD0126E5F77731B4BE6F50DF189A74A4927CA038C8B3C269E61DF7E5A3AA93C0A572AAA218988F5FF8DAF042F7A58CA36A069292812F8810374B768EDCCFCBA337AF9C362353942243146BED5F62921A252C378B5F9B41B6934EDBF6ECD7123273818276870CCE45B81AEE4C971FEC69A75249626821F05651786E952F3C533F525FC8B7B5F6EAB33C320532774256C42C01B7205AD6265ECB324F364F6785D5D54BCDC595B252BA48F4933C74F262A680E908D6217F81FD778E240D7ADD32B568DD00B1A2FCB2CB70D39CD39632D4883546D2FBAD0748DAE6D34E090694DFFFABF7705237947C6C8BBFE827F97009544A56B3FC94F67A972F2C5EFB19748EFF9B8ADB783E114470A7ADBBD1595E490846DF2E9531BEE796F63A1166850BB6B1FC2C14F429282EE3AD5B213835E8445F50C8711E06296371F912EAA6CBB756BEFEBE373FA80A7CE147BCF84A12E39FF68EFF2A0D40F44A304D170F20D49EE207611E67EC1AF24C244C49F842039DEB0728CBBDBD50BABB546CCE699E32FF668603387FCA38ACE7C89BB8BA142F52706D6898888D6BF4F99999E0003FBB62CAB4536B066517C8F7D022DAF488FF6617304B96D9CF3D45C1845E2443C59C3A6F6B3ECB173E9F193421AD77C449D96218488343F9E7AFBAEE2139078547CEBB62ED5FB12024C936E9D1F56C1852B392346F3B92219D09CA83E89F7EBD613518B29DCE4BDE26686F75617CD7E7690BFF58D520B16D87F5522F4F8BCBFF808BBFCDEB16CA08FBC9E71104E2923602D027C1C3B8AB9EF1F550C138970A9C21AB3A416A23BEFDF57D8091BAE54A636CEDD05596901D581308048CF77C5A0270D8AEEFCEC454CC1879C0B59C03AA4A2526DB6D3C2BF48482C8B47969C49E480F11ECD54C6A121CBBF1EEEDA08DF309F919EB484C1718CC373C8F29E9A8DFBDC3A2B64E3E3C91B5E5819F7EC4F8EA190F40374B43CF65D8EF9ECD2430C171123CE4FC643D3B1296A8B35DC8F29C4939BDA0D6BA4E5681A0304FC0B131D9CDD4E92FC48AFA4C6771F34D762CF151616F7E44C00EB5A553144FF3D2214DBFECF85205B8E060C4B7A9039A5A99C62A2C95B5FCCE42888BA45EC5FB1A8E6D7C49786445552370E45116E7DCA0129838B9909648A6F20EA06315FE643D660DAAAEC5167B5C204AECE536812E798F69E14F634CA9EFD711AC7B1A887DB433AAF6AB84BC2650ECBC864894B6B01413530163B9A0E0C93E7D67CBDCA1AAC561A35E4605BC37B452D469E01BBAF52CCC9E08329875F1558D7293BD73D7992CF3FAE2BA844CB4C3EA1BE890375ADC66CB1406E6AC043C02FB6CCF652186E8D6A59ACF284C0A4ACCF7DC8F7E57A94E3321B3839E2CF469EA737EE6E8980549B76829B29234BD5F877ECB298B21DEE6B37D5E46CD3403AC854FAE1BB3E08DC7096491F6CC7BB937FF4BE3FEDF68CD6538745BE7E760FBA1B9068DEC40641C3F3897DD9F90EDEB78530F6474539A9F61A0EF0528BE905CA2A512AB8B3E98CA0F0F7860E14B9412266F74B88CFE88A99935B38C4CC18BFA4791CD3B5575005419528735F9DACEFB259D167C250F782FFED6992436F35D8BAC8DA7BBBD8BB525F614A9CBC54CE98DB4367290035D15E957CEDCE9C84F52468ADD40F1788B45792FBEA514FACE15787C6DF86867A7E9BE693DB1C8876CEFAB16E60AFB71D66693D046C0C7ACBF96FE51188E61F63289DB8D1FF68FAD8E979F44E9C4907ED2DD3B9A11C23B1E7D472DCA16C3117E29333C1559AAB77B6F8A2928F9CA8D8677969D41668D7FD849ECC63EA7887A097B957AB6A2EFED953F2401402C249863E1A48015763F426CD818764B87A5EFBC29FABC1420FD78852A1BD727A634E2D7631B4E8D13F653E9AE9CAF331C27179E42233EDE93BE998524A329BEBB41E16943FA0B425B3184E6D756DAD71E4F185A601C5AA07468CFEE447841524999292C6A366EAF6525E276DE21F2FAC66F938015652AAD176419143762FC7C8C67FD0ABC69443C5AB5728183205B8C4C2197A9FD0EBCE2BCABCCB92ECE940534C4308E93F3850072784A16D4AD96220C1E824EF9053CCDD76CA78D834F1085D91AF9195A029E1E7445A67709E9EE2919DE4BCAC1C0FD2126A432D54E8736BA51CE906D9B784F43275F88E61B5E05A488BD7B2613E38D832166F4D236136FF3B88D0795B9937667F523BE902BC11604EC956A00CA3EDE437DA9BF9EF64C8F2288E92CA2B72587FA01E0E09D4AA606C8BB2F92CB9AE4C8753E910716EE44FC3DB7FF5884866463B0D0264019B39C4065CAD037911A44C0EF78402497E3CF7318F12FA666F555511A68AEE13448C3D7AB7E45480DDC241E0CBDCE2299E497382DFC84B7E455965CE6F9C9B64AFDF6C89E31482A0844C525AFF963280D1E00B4DB9079EC897E3DA2AD187FB81006F09E35E2A00B7B5DDBF6383A0F722233D1C8EC17B17537CA446CB9592AEE7CDB6D76C9B56A73E0B90C521BC745221FD083800899BD6CDF33ABBCA54235C522A744EF6F3A990853958B0C8C25320E3246BC43691379018A93CA28F69FE315C20E583C58BF0748C4546D89760E314F2E9A3222D641D6B4B963E4949F5BF278A1551BE72B2565AAE225D877EE56409CD9DA5D0CAC8E191822623B4E4AEAF5FC3E3700096E0C5942C3B97E65D138AC6DBCE6D8788535100CC0089017545E5697924F3A0EC31FFBFEB19679F1431DD0A607F173DD466F98266B1248D425B7E32F0360047D58BF1340BECB1126C3818DA4360175C6D7D8CAD5FCC1BCC9DC36C4E74C4FDFB70C62A98CE75466278AB3AEA9E6B79D16C4C75432317B375417DEFFD5846584F0AE5B05ECDCE6C99B3A03C216BF45866B1EC12EA0A5F7587C6DE1C497A2E08B85F385B71569EDBD406D93B3B1D0DB2E7F557561CD36E737C2B43E298AA9739004BCF55D7C96CB1438F2BD7BEABAA9C64B58932AEA808BBDF30FA4D363DC501741CF8A43AA1039E7B46576B8B299AE300E7BB49B61FFD29D0F814857931FC2AF69E6988F12C6731D619C20DF1D7096DF5C656C765A35DBF099EC5AD97B54F5A40128182B0508A6C5E6C7BBE9958F290D76637909E4759AD778E6924255A7AE038296127F00124B51F5F3742475E68C2BA4B2BBCBF39CE7463999A2C95569FADBAE6F80CC073BEA063CC5587D9DB5962C9B392E6FCD143F95EFAB1F619EFF7FC7CF64FE3D195916CB53AE2A956880EBD9EB199B87E5FC55D497FE261DE93C129564E90DF1BB21DCF41A53EDFD430213C35BF4D85E860C04C06A7CFE8126CE520C1286A24D6872949B702F09581F8351658CB86D44C1629B4A0F24BE07CCD39DD21D9AB8DD1B082462AB67338D0326B481CB4BD541D25DCAC6FF5A98AAD4B5C6B50BA0F7177C4D40964B46E96EF198309222D50005E1ECD5458C71473466EB2693B3EA732309B19A3EA582099C4A16BADE4850097BCD495BFE8DF97E1FFBBA29638CBFD8D841549FB213EFB29AEA862D6AE28FD152820CD0AB67965C2D08956016C4DD6D24F94BFCC9A396BAFD26AC085709F5899C4A6831E8DF072A96A05DD8B854963BD0F2346F13E5FDB7050BEB13B4DDDE99B2A60BB4550129FE53E049CA595351E29A07CE7828F387468AD313E11040C3C0C2F42DA056A311FEB561DBBB9910F080485FE31B1A3C46D44000BC619C578B387C7521E4CB99000AADAC71BC2FE7CE8EBEBD9EEDB294702EB294E0E2CF639B6766C12416A3EEFA84CE71C8D630851B5FC5C57F80F92A119F07CF623DD1CD80988C7CE6B6E1688EFC9226050ED3494822309E2049C0ADCA80327165283C8C8028769134D9FF9DDC6769E4EA422C5777215EF7006B8EB54FE5298D5386EC0AAC906B03C5E1180C5E2AC69E1C93053DCC41921E66F976CA35EF242F2A26C86F311F7B998BBDE5B83C547B4039F44B0DF8ACFD24F2928D4CFBE7DB647ADB1FBC95A7E2DB518A5A370D9A74619283F4F77F159BF5CAA1A489631458F8030C645731078489A144DF87BF847318F420FF5A611B4AB8D7E3E4DC2DD74F3C91E7ADCA32E4D4EF99C0410664A32B50A85D2AF82006C859378791E86DAF7C94ABC34C166B9AD0EC287AEB8F8E275E45C51FCB7EC3EC5B65668A07F8D8DCDF19F201DF1FD0134B3309212EA13CDF3E0A25CE16201B0A69C2830B7AE5F7F8A95EB38399BDE01FFA81D642147D2686E56C213C42F3866445F567252A47A95AB5AC483F2BC6C9E269A9F75349768567159BAF00B0A5809ADA84870721AFAABC61BB2263167D70B916871208C64794C929BDADA24D89393E40747EB6F5E4316FF5360AC876F726224F5319332B90CFDDC2AF9F401EEC6BCC002940EBDA36AD04905B209DCAC11C943DC58565D53E260494E7A3266533A0B6B98D21D1AAB449F08981B01B2EFBAB0ED4E7126E54ADF47F5C8C45D3DCF2C65ADBC8989FC7D5263040CA402B76897811D409D1B04A0C80A078ABC9C4567AAC088F1C20210FEA960236D485728326EE3515B05BECDDE2D1FDB5549260FC023A5BA9BB775C14001F88A4C5B35BDCEF9858BB8660D1ECDB0A780FA439E5E38E96BF36C1E97BD80CC0B11A704EB2A73A2E6C0495FE780397C157CC378F2BFFB86014DFA7774B0558CA6AACDAA5D29CBCEDA55CB321D2B635EC312BDAFB30C45C006D8248D6F8F80D037EFCF94692F5DCA16E244D665DDABEB2C39F0011BD0F624E30D2F6853DD46DA56AF67E51D0B34C9D075F5BC3A90393FC8F5E96CD8E029A7901191E66CF79D64651CD6B95870F483A39AD9CFB53B5D1C66FF7CDDDE4FA42405350DAD3B010F645C5175461EBAC27731FA4466461AD472A0F37B531227A59AAB687D14409213EEA815AE4F925BFAF43276947B28F965F99AB15948FE8074F7130F929E481041DC9372B7B249E1B8A5AE6FEAE678C1DDE54520167ACD1CE98EB678DDA102E7F3B8B432228EDD58AE4AA4CF9A24ACABE95DB1F544421B177E30F32443B8A13732A45DDEC167958C4E7A35E65391C59617EFA7E4A18E0BFFF6ED42A494B070D7298944A7A2654663BF1BE91C73F023B6439BBD4368A191E1B31B4229329E2E81949E46F2AF68609AD9A72DE6F75FA4725A4B50012BAF07F460B04FEB6B15483EEE459135B6EBE5EBA62493F23B4B046F1D712FBEC4E9DBA3FA5D0CA2DBCFCDBAC154771B39385F0F0834779D6B35F888FC881A47BCF4C074FF9195B18685B30DDDE3899D3E0D553FBD6EF5F8788BA2E977C93551E92288E2149804A3B64743ED730D265E82534D123563B3D3311264DDFF1B884043EAF01B8333944BAF360F09FEC910F44AB8AB1406FCF4286F04C88250CE337995994A9BE19B0599307A0557F722233BA3D325EF2F2C4504ECB5C157CE80267942DDB304A4CEDAC15915639B162776C4C853B98E9B45CB12D03144696C1DC81F3EC75DCB2C0D7947683F1E39DF344E30DEEB7F21552AA6720D81ECC47EAB91988223172920012B0DA85B78F80027C3FDA06F30E60CDF1F9DAE40188F51DB83767E6550FC97C66BF183E580F55A9FA682504A86C4DC29E81C6AC3973D24731C630180AD764938B71DEEE937DB1682BBE9A4C7D49349B615B688E13F3DB8AE25439F4686217BB31974584320FAFE77E167386C6D54CD8F9F0082DDF6CEEA87673F2D1B5F15A12A8A844D2BD55E7DB2D842E456B321432C62623C4E304B20230E7837D67F4DDF293F46520BC957FD952234605126FFDDEEF94FC5E77D2013D1A49CD7020DDEBE9E8A704BADDF4EC56E2A47AC02E134BA6B1CDA80FA5A0E2530E4866C99B163C3E378CC770FA5E3855CE5C146583D3783474F83187F9AE5936FCD448BC8CB91E2E29965368A9F3B140D9DFA6E95CCAFE976A93C6730B6149CA739816C02F4EEC2600216CEECC8C14073CB6C93A6472119345BB0E0BD96E557FF284DCC19F90784E39AD0EA77708A37DCA7AD9403FDC6655A45028D0393804F7A4249D3F592998DB96950F78EA46592CC53A0C197E141F930F58DF7BE81FED9B158E3F232D4DA926135CE6CD8D16FD88C43623D13F2401587323B822F581E3D2935AF2ACF3E4FDBB682CD9E0D2C09C995B47AC930AAC36CFF6C556B94E1DA0561151EC280806EAB7F9ADD950B791B720DA3442BCD0BA3528FAD1E11997E3FE8DDD4496981630F6D664960E5DA44984A2025499BAAC975C12F57CA9F5F425242BE527C64CC062463D03F93530157A256DA1575AB97EA7528986AEA76D5B1EFC34A81B809F5979700EDC9D3BE902C28EBE1741E1F1109F5FB1BED02631FB0F25867119BC63D6443A22013C6B38B1E2231DF0C5E1CCC1B05E34917285B003AA9E13011458B2F776A64A63DB3BFE85675F8DA25C8E697D594A6F801E78EB375472F039DF556B74FA908260F1CFEEE87B938CF6ABC4717039DF7F29E31F503CD38BC3FA6441A0CABD24C7EB9685C1971EA977CC7166F3C6FC857227F04C47B239BC9B66AB1C900CBA95637A72948037601877D8AD8CA60D935C2D4A7175ECE306AFC15344DCBC568EF74EEAF981B4C28AB56B2DE51A8CC9D3F2D61B06189CDEFBE371C3442DCAFFE1C0555ECE43523C5D00DEE2C4AF477C773A4CC02CA63337489DDCCD645E6D10268083B3A148E09D4902A3E15813EA8F6E27FFC022B144454667BAA3A67D01FA2DC0F26FF7721EC6F0FC13AEFFB2F7111D181B57978277BDB694F6F34076895F91A078F2BEC3303AEF47F5EEB898164CD4D80426B9593B0F5473C6B2BB947FDDB377A957521F9417DBE4162A1A3842218EC2F87FA87D4702E2A4766B1A8D14CCE492DB85F7D028D0E77CD29CA26221E1A738376378E1D7D611CA9064D021FF37C4F90EF5CF75762DF8C79474D1CC66D1B655BD5E30AD8C0B7676E8E96F8BC155CC94584E4D5FCB1BDFCED948F8ED31F5241E591DB6C53EEDBAD4B167299DEFD4A9E7C64EAC9AE5B1BD4C0C8BC29915E7B2E0F32407040F390DB5DE243106CD74B6FD02554FCD534D9FA3DBB34133FE1AB83162B5BFA019B27874CA226AB586DB37DB60EEE066E2E71A74321D15254C8611EA500329A050526E6EB229745EBEC1B2E01AAEFA4D4A839DD60C5B5B4F41AFAAFB3DA78DFE5A3108B837BD3F5EE623D878D39AE6C77F4CCFAB9D0F572018F46BE01E0CCA9DFBDD6C6438F7240CFCF1C0C25231D72A2C48EB9B553275B299DE98D02B15075398A837EDE94A85BB834089F969C06B45D5A33C548ACA31CB006D5C7B4B2CEE7E346F96415161D79721A22A29D8B2EDC3ED99B08557F5A170BC0EBB6526821BC5DB7297AF25DE46570F975BA8B5845CC7FFA5A74C201B51A90A2293B45D77D52F90A2B9AB42922379DA819B6B54138590D7E8ECD8B50F455C492B85ABDC1042E1ACFFACA92B0CCC629C1135DF4DB0FC76330043CCDB2E26DE48574113DADFCE23B146BBE8F5C22D501778AA5DCBFEE4FCD0173BB60EB93A0796E6E2E4A13676B39A5BB5E4D7A3E292DD20917CA3CC170E12C5C933036A31D80080BAE9B45574D70B5282859401145DE90810D0DB0D6E76A222D36E483C3CD9DFA0923696B024F0D06ED83DE0E56F662C3F0884CEACAC9A95F6632889420E3E57224F43C6EB5888DCC95F14041B66096219D49B3186C94477432D47F605788B34F491FBA6657772651BA8F9DB8F469898315AF514FCFBCE15FB82AC5B2C043346B152E1632635C708D61A000E420813C3A31BC1DC1352EFD258244DC3454157882E19486D6A74DA1021A0431A2FC43D03B7FD8993422D30027183E8B2BC727DDE4AECE3DAF454D6FB7BFAA4BAEC281100C2A59D2530AE67421DF76D8E9D01EA507544BC8799DF19FD2FBCB214D3B80435B5BC9040051048B02390EBF080DE1111178A915BEB018E3EE5A43B483A1526532CCFB48221A7319EAF8AE2215C37D7A7684FB7B924D9079EDACA56BE7B57AAFA979BC20992A69745E91A3B74911D238033AD90B8C6241F1D72C1CB8B2672841F61119B5A6298D5B34213384DDD540B965A600C682540A3BD8F466AA25E75CA34883E68EEEFEDE502BA7665AEDC133707A380627F92A990E2E27874CA226AB586DB37DB60EEE066E2E71A74321D15254C8611EA500329A050526E6EB229745EBEC1B2E01AAEFA4D4A83E93CC0DD26A8D770423D127B762AF62E3F3BCA02510AA7C67E14B038F075C5C0511878324C47DE85C28C9CCF10245325D5D52717ED331EDEDBBDFCD4DC61A9E63100328197EAAA40DD8600B21E1C8AD0AD1187B69E29FA78FA7D618F7F82B6100C102EAC3DA727F9E322543355DD0128F5420E17564BA6638CD784D9E9A83814EC0F46C6F2113F35D12117F0C93948F7C789DDC46EF7842E95FC78CB961DC312ECB58ACB1EF0D614F2E9F144D464124EFA9E06148E78DEC111050B93F0BEAE9BB408392FB4506F350DB7ECBB6E026DFC61336D130B1EBFC9A702DCD80915BE21C7372A3B767068E27040CC5679158C166C159794AC3FF300F5F9E53C1F84420B692A14500F98C72FE2E52D6643D185D217CFAB3CD9EF9C41BB297F65E164B654EEC777CA127A0173197179A3003783C2D48F7C2E1B257FF189D40030776CCA162E0F130F1798BFE2B588CEFC16BE109B03BF936AC25A28785951E49DB104AB23BBC121C5D5D6BF441E2A49B61E8E201346EFDC76ADAA55CCEFE4BAA25C540483096F36D767112B16009FBF74708EC3E38982DFE9B31B75C09B524B91E64461865BDCAAD85445D208E013874415964E448929D746C1AE26A6B932F919577F60E836BCD7937E677BA4D8134820696116850AB81F22EE3691BB4F306FB9F4029BD87D3C9BDDE5ADC1B3578F099809A8FC88BF3866E9428B6DC2FA66C8FF172A1283B3FA3D76561CFAC53DF900A895DA44CCC9A34D99C46C056243CF601CC3D2E300B32F60C74E739932A2F2CA0B2C91B9C539B885A4A33A164D35B6949BD5EE060BA28D02DF6672F5FAFD386C1CC5FC2E3AA8D1B1E91B8CAA7A2CD45EF78E822DE10B4AB0C4941DC4C01A4FC21BCA8BD1843ED0914E511350ADB4DF15E4561083C59754749A5726637CB64200BB665511F59B37408568F438D8FD0F8BD34BE5B2B789F5C733E1DE46DE6808F06311152E94DE6173B784FF6E0B367FE993993E0C3065925CB492F60F023B00423670119FAE218E54A5CC0C73E08BD6E8883F0FBB83F243868D609889B0220D7997728ADACF39B885A4A33A164D35B6949BD5EE060BA28D02DF6672F5FAFD386C1CC5FC2E3AAC3B31671BE86983D2FC361C7576CB730B4AB0C4941DC4C01A4FC21BCA8BD184BDC143E13AB03AFB8B460FC86564C5797068DDBE9995E5B798B9993DA100D94B05C0EF0620AB84CCD3DF8FE4261FF4BE168B4B471FA03FBFDB59820DFE0BB59532D82B88E154C051AAE9F7C2DE99D8F348F3682415A25EF8BB1DC0A5EF37015CAA780A19678FB2BD1299374BC9F7CD3F416A96D70D0C8BC84ADE068F1CC158D89A2073F04DE9A442482670A75534D8E2075929024AAED011EF7B27582DD1DB65B3EC7CC7FDED33037E8F56BBCE353156F268D9BE25F3982EBB4731646FF7E5A2854A243B2381D6AC9A8B3C40476B25CBCC362DCEE464C4099972FD4A763F48D21A6FE20FD68323E6DEF620F656CF28E41D8E14E6438405C2B22728B7AB9C088E413074EEDE5E07B4994CD2049A185678BDCC0F26D406900C223E3D3D73966F8935A072AFB238380778EC85DED3E9736DFCCF9C7A402173B8C5C616CD8E7A8EC8B9CC837A6C7CBBA15E62E6C50A7A828FA1C0FC246AA805F1E4CA1B6FC1138CB35211FAD88DA43E92D5C73201AEDD60B54F5E5F3875B6B412B6ADC0980821E0A16DDF2202C2097C974C14BC490612D356682CE5CF702E6CFB49F4F8B6318322DECDC96FEDD79B47848B2B517A6A0A519C46A0F17A81817F1E50D36B94BE0A2D1D018602B2645F3C0EF839BF2874DFB5AB6BD5F8B4EBC52574E2E6FBBFE698523E6F84E8906CEB38CFE07B333AAB0DAC201878E9171BB0EB56A753E4FDF8A4504241484214D578263A3DD058187C4EA24ABDFA707BD1004A9125CEBBC8913F250CCF4EF4AA2D4B89D689CC8E99EA12BE553B8DD975350EAE6D121543C13BD03DBDD57ECA97C16E6461C710CF4052B84C5821BEA529C55227F401E4BA9EB584C7EB26648AF893F20E3C73E038B2C76DF8C2CF35EF70F55C25CE8F59EEED9164FDD8C3D453708E101E456346123448D658C94C0869AB7674CE7EFBD6258F1FEC412F8941F11017D143F2C4CF0FCBC32A3002C132208834E3C52CBACA4AED32A44BD9B515936CC0394704099B511F18BF3F35BCDBDD1A76E49A45DD5DA51ADB54014B3284BA7A5BB9A69A60E35966EE12ACFC9780CE7EA0CDF220AA0E3E7FE30E110704BD91D2E08EEF33345845CC663BDEDE1801D04A682119B6E7184BC8EEDEEDCE8F8D62191BFFDBF4852356845FDBABAA4FF5809935FC86BD21360285E6F6081AEC6B26EAD2CF3B038A05381C7153DF51C7A36B3EC1A54AA44F52B80B855C90167BFA28C21458F4715EEEDDC9E43C5D9C23668C7615484FA19E9643032D91CD34E8BDFC213DF36EEAF780C444E50E01E9AC6804CFAA9F2E0BB0115F7A16179A22D5853C765B6A6DD59F2393DF15051182E6EF1700227477F25B4F74B99D0064AD68682D5120D932D827A4C795468440BBED354761639E22B305346FD74EA67E9D1D4A6F4B9F08ED159A62A976180874940B891E189B2412190C85BD0162382767EED017D37D9AC7579F3136D3D38DDEA358FC0D7DA7E2D81AC17EF82DE6BBE5065B37FA86470F50933A143841658747F47779B3C321E4CE4C22363C3F31F2196B65DF63C56FD9E2EC886CADBEAEF65CC4A8A00EC3792AC5FF6691EA37CF4B7C7EC938D0DE37CE22A11E186C13299EA4803085FF7BA0771D7B376E5866FD45B64B9045936BA753A71E2B10FC7B21579FF84069562AC291E11D35235DD45C87A6F7A016F9C24F7D60C01B7E101155C90F0D3808EB0528FAA080769E5E3F6E29F7C4F97626E202A32C47C7F62732DA5BF0B6F492F4BC56550DA1A9371BBBD7D0B1F026BF41573CD2EAFF09884CD0071BCCD5156F849FE6F8545CF58F14B969520ECDA988E531A36CDB5031EAE88850E1F33C4FE43E61B0482AA0B198EF0194EF383ED964DF673FBFB6096C0844087D47B39D57ECE891059A623AAF24921B9BCCD56818F43462E88FC0415F58370CFD8C9087C23304AB7F39B3E1CEF3E035B93AACACF681610BFEA6F41FBF1A8D0D18E91252E938120EA579EE755F8735AE26E651670D344A7178D0327166931E90B35D1ADC9F583D225B1001E50CE8B0791F2E02FC1A2B5631D9D27A79F2E0DB0073CD029F40A2D73AA495F3F844CF22B1C383D70C43D90530F59922BA8D297A3B38B92C21321AC900999094B6E49F5F8E67E8D3986A8D6B1F7F31507288508615F0EF11143344A74B798845BCAE5C3880E01014A37FD18A1025B51A3EADC8A927A52571A2845CB71AE284A8E4802BE0B8944104E858CFDEB9146634E9A40DAF7E7CF3D3D4319C9E6B0D2B0ED90BE7EA0AA987F8A58A9D5BB6B36FE0A6BA8F1388CFA586376672795FB3F22E743C55F099DE488217F97A9BCDF74289975DDA109F0A7530D03AEC15D57DA947AC0C653EE57887745655A5DDF88B9B40B8C576F244209047F6CEE2A0E714F8DC883232E283F9E217C6E66AC6AAA17285BEA81B15DCC5872435720C2E462F1127C3B41BC1405B80FFD4E3B5C652DC22DCB3BD0389D7E2D2168208CB590EB7302FFB1EFB037CEB53E5D1830507C1572D6110161E921E6FFC49DB4445DAD603FB4E83220DA450CB9EB4D988DB3AD6C9D36FD7D50BB8052DE49AC9B174098FF92189817CFA066D9A4098ED588C45148A54D67F8DB0B0C8A17FF049AA87EE8DFE2F4F8B7284CC0E041758F4419C11005EA764B84575FB61CE2E09EDF2BEFD4BBE5AF2ADFB2437B10717F396F899D3E30431779A2B492DD6B578B9B458A8B11AD1E8DFADD3834DA854FCF95F81C4FA2D8F96D3E4F860BECCB4C2C3D10A6FB7750D09D4DBC28FEF753B16F536C5FAA942D7C30B9BD0BE62AA96DF892EC27B8B16A54947441C30EE4E0180A19E8FA094D3DCCFE591ABA767AA6F7962DE2E2373DD45C3C88A7B2915 \ No newline at end of file diff --git "a/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" "b/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" new file mode 100644 index 00000000..55c284fd --- /dev/null +++ "b/spider/js/\345\212\252\345\212\252\344\271\246\345\235\212[\344\271\246].js" @@ -0,0 +1,136 @@ +/* +@header({ + searchable: 1, + filterable: 0, + quickSearch: 1, + title: '努努书坊[书]', + author: 'EylinSir', + '类型': '小说', + logo: 'https://www.nunubook.com/favicon.ico', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '小说', + author: 'EylinSir', + title: '努努书坊[书]', + host: 'https://www.nunubook.com', + url: '/fyclass/##fypage', + logo: 'https://www.nunubook.com/favicon.ico', + class_name: '玄幻小说&魔幻小说&悬疑小说&历史架空&都市小说&言情小说&武侠小说&官场小说&现代小说&战争军事&侦探推理&外国小说&纪实小说&诗歌戏曲&宗教哲学&文学理论&寓言童话&科普学习&社会心理&作品集&传记回忆&杂文随笔', + class_url: 'xuanhuan&mohuan&xuanyi&lishi&dushi&yanqing&wuxia&guanchang&xiandaixiaoshuo&zhanzhengjunshi&zhentantuili&waiguo&jishi&shigexiqu&zhexue&wenxuelilun&yuyantonghua&kepuxuexi&shehuixinli&zuopinji&zhuanjihuiyi&zawen', + searchUrl: '/e/search/index.php?tbname=bookname&show=title&tempid=1&keyboard=**', + searchable: 1, + quickSearch: 1, + filterable: 0, + timeout: 10000, + play_parse: true, + headers: { 'User-Agent': 'MOBILE_UA' }, + + 一级: async function () { + let [cateUrl, pg] = this.input.split('##'); + let list = []; + let cateKey = cateUrl.split('/').filter(Boolean).pop() || ''; + let cl = this.class_url.split('&').findIndex(k => k === cateKey) + 1 || undefined; + if (pg === '1') { + let html = await request(cateUrl); + let selectors = ['.listBig-li', 'li.listBig-li', '.book-item', '.list-item']; + let items = selectors.map(sel => this.pdfa(html, sel)).find(Boolean); + items?.forEach(item => { + let urlSelectors = ['a:eq(0)&&href', 'a&&href']; + let url = urlSelectors.map(sel => this.pd(item, sel)).find(Boolean) || this.pdfh(item, 'a&&href'); + if (url) { + url = url.startsWith('http') ? url : `${this.host}${url}`; + let title = this.pdfh(item, 'h3&&Text') || this.pdfh(item, 'h2&&Text') || '未知标题'; + let desc = this.pdfh(item, 'p:eq(0)&&Text') || '无简介'; + list.push({ + title, + url, + desc, + pic_url: this.pd(item, 'img&&src') || '', + content: this.pdfh(item, '.text&&Text') || desc + }); + } + }); + } else if (cl) { + let apiUrl = `${this.host}/e/extend/more/lsmore.php?page=${pg}&line=10&cl=${cl}`; + let json = JSON.parse(await request(apiUrl)); + list.push(...json.map(item => ({ + title: item.title, + url: item.url, + pic_url: item.pic, + desc: item.smalltext, + content: `${item.smalltext}\n作者:${item.writer}` + }))); + } + return setResult(list); + }, + + 二级: async function () { + let html = await request(this.input); + let VOD = { + vod_name: this.pdfh(html, 'h1&&Text'), + vod_pic: this.pdfh(html, '[property$=image]&&content'), + vod_content: this.pdfh(html, '[property$=description]&&content'), + vod_actor: this.pdfh(html, '[property$=author]&&content') + }; + let id = this.input.match(/\/(\d+)(\/|\.html)/)?.[1]; + if (id) { + let baseUrl = `${this.host}/e/extend/bookpage/pages.php?id=${id}&dz=asc&pageNum=`; + let firstPage = JSON.parse(await request(baseUrl + '0')); + let chapters = firstPage.list || []; + if (firstPage.totalPage > 0) { + let reqs = []; + for (let i = 1; i <= firstPage.totalPage; i++) reqs.push(request(baseUrl + i)); + let res = await Promise.all(reqs); + res.forEach(r => { chapters = chapters.concat(JSON.parse(r).list || []) }); + } + VOD.vod_play_from = '努努书坊'; + VOD.vod_play_url = chapters.map(c => { + let url = c.pic || c.url; + return c.title + '$' + (url.startsWith('http') ? url : `${this.host}${url}`); + }).join('#'); + } + return VOD; + }, + + 搜索: async function () { + let [url, params] = this.input.split('?'); + let html = await post(url, { body: params }); + let list = []; + if (!html.includes('没有搜索到')) { + (this.pdfa(html, '.search-wrap-first') || []).forEach(item => { + let url = this.pd(item, 'a&&href'); + if (url) list.push({ + title: this.pdfh(item, 'h3&&Text').replace('小说', ''), + url: url.startsWith('http') ? url : `${this.host}${url}`, + pic_url: this.pd(item, 'img&&src'), + content: this.pdfh(item, 'p&&Text') + }); + }); + } + return setResult(list); + }, + + lazy: async function () { + let { input, pdfh } = this; + let html = await request(input); + let content = pdfh(html, '#text&&Html') || ''; + if (content) { + content = content + .replace(/]*?>.*?<\/script>/gs, '') + .replace(/<\/p>/g, '\n\n') + .replace(//gi, '\n') + .replace(/<[^>]+>/g, '') + .replace(/ /g, ' ') + .replace(/\n\s*\n/g, '\n\n') + .trim(); + } + return { + parse: 0, + url: `novel://${JSON.stringify({ title: pdfh(html, 'h1&&Text') || '', content })}`, + js: '' + }; + } +}; \ No newline at end of file From c24940ed0128365be29bcc2d3f45a98974e06de7 Mon Sep 17 00:00:00 2001 From: Taois Date: Sat, 17 Jan 2026 17:50:26 +0800 Subject: [PATCH 34/99] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0drpy2-fast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/config.js | 55 +++++----- public/drpy/drpy2-fast.min.js | 102 ++++++++++++++++++ ...76\347\275\256\344\270\255\345\277\203.js" | 2 +- 3 files changed, 133 insertions(+), 26 deletions(-) create mode 100644 public/drpy/drpy2-fast.min.js diff --git a/controllers/config.js b/controllers/config.js index 34a1d68f..1b8aae62 100644 --- a/controllers/config.js +++ b/controllers/config.js @@ -327,9 +327,12 @@ async function generateSiteJSON(options, requestHost, sub, pwd) { } fileSites.forEach((fileSite) => { - if (enable_dr2 === '1') { + if (enable_dr2 === '1' || enable_dr2 === '2') { // dr2ApiType=0 使用接口drpy2 dr2ApiType=1 使用壳子内置的drpy2 let api = dr2ApiType ? `assets://js/lib/drpy2.js` : `${requestHost}/public/drpy/drpy2.min.js`; + if (enable_dr2 === '2') { + api = `${requestHost}/public/drpy/drpy2-fast.min.js`; + } let ext = `${requestHost}/js/${file}`; if (pwd) { ext += `?pwd=${pwd}`; @@ -348,31 +351,33 @@ async function generateSiteJSON(options, requestHost, sub, pwd) { ext: ext || "", // 固定为空字符串 }; sites.push(site); - } else if (enable_dr2 === '2') { - // 模式2:只启用T3脚本的T4风格API配置 - const t4site = { - key: fileSite.key, - name: fileSite.name, - type: 4, // 固定值 - api: `${requestHost}/api/${baseName}`, - ...ruleMeta, - ext: "", // 固定为空字符串 - }; - // 添加isdr2参数到API URL - if (pwd) { - t4site.api += `?pwd=${pwd}&do=dr`; - } else { - t4site.api += `?do=dr`; - } - - // 处理传参源的API参数 - if (fileSite.queryStr) { - const separator = t4site.api.includes('?') ? '&' : '?'; - site.api += `${separator}extend=${encodeURIComponent(fileSite.queryStr)}`; - } - - sites.push(t4site); } + // else if (enable_dr2 === '2') { + // + // // 模式2:只启用T3脚本的T4风格API配置 + // const t4site = { + // key: fileSite.key, + // name: fileSite.name, + // type: 4, // 固定值 + // api: `${requestHost}/api/${baseName}`, + // ...ruleMeta, + // ext: "", // 固定为空字符串 + // }; + // // 添加isdr2参数到API URL + // if (pwd) { + // t4site.api += `?pwd=${pwd}&do=dr`; + // } else { + // t4site.api += `?do=dr`; + // } + // + // // 处理传参源的API参数 + // if (fileSite.queryStr) { + // const separator = t4site.api.includes('?') ? '&' : '?'; + // site.api += `${separator}extend=${encodeURIComponent(fileSite.queryStr)}`; + // } + // + // sites.push(t4site); + // } }); }, param: {file, dr2Dir, requestHost, pwd, drpyS, SitesMap}, diff --git a/public/drpy/drpy2-fast.min.js b/public/drpy/drpy2-fast.min.js new file mode 100644 index 00000000..8d397161 --- /dev/null +++ b/public/drpy/drpy2-fast.min.js @@ -0,0 +1,102 @@ +import{cheerio,模板}from"../dist/drpy-core-fast.min.js";let vercode=typeof pdfl==="function"?"drpy2.1":"drpy2";const VERSION=vercode+" 3.9.54 20260117";const UpdateInfo=[{date:"20260117",title:"爱佬新So测试版,使用drpy-core-fast.min.js",version:"3.9.54 20260117",msg:` +drpy-core-fast.min.js内置了url和sqlite模块 + `},{date:"20251007",title:"爱佬新So测试版,使用drpy-core-lite.min.js,内置了Buffer库",version:"3.9.53 20251007",msg:` +drpy-core-lite.min.js 内置Buffer库 +gzip和ungzip改为新so的zlib实现 +内置RSA对象加解密效率提升 + + `},{date:"20250801",title:"drpy依赖更新,使用drpy-core-lite.min.js",version:"3.9.52beta3 20250801",msg:` +drpy-core.min.js 更换为更小的drpy-core-lite.min.js + + `},{date:"20250729",title:"drpy更新,所有依赖打包成一个js文件",version:"3.9.52beta2 20250729",msg:` + 1. wasm支持 + 2. 引入 TextEncoder、TextDecoder对象 + 3. 引入 WXXH 加解密库 + 4. 所有依赖打包成一个js + 5. 增加 buildQueryString + + `},{date:"20250728",title:"drpy更新,增加tab_order线路模糊排序,优化解密算法支持文件头",version:"3.9.52beta1 20250728",msg:` + 1. 增加tab_order线路模糊排序 + 2. 优化解密算法支持文件头 + 3. wasm支持 + 4. 增加 removeHeader 函数可用于清除js/py文件的头信息及所有头注释 + 5. 引入 TextEncoder、TextDecoder对象 + 6. 引入 WXXH 加解密库 + `},{date:"20241126",title:"drpy更新,优化去广告算法",version:"3.9.51beta6 20241126",msg:` + 1. 更新龙头大佬提供的去广告算法 + `},{date:"20241104",title:"drpy更新,增加新特性",version:"3.9.51beta5 20241104",msg:` + 1. rule增加 搜索验证标识 属性,可以不定义,默认为 '系统安全验证|请输入验证码' + 2. rule增加 searchNoPage 属性,可以不定义,如果定义 1 将关闭该源的搜索翻页功能,超过1页直接返回空 + `}];function getUpdateInfo(){return UpdateInfo.map(_o=>{_o.msg=_o.msg.trim().split("\n").map(_it=>_it.trim()).join("\n");return _o})}function init_test(){console.log("init_test_start");console.log("当前版本号:"+VERSION);console.log("本地代理地址:"+getProxyUrl());console.log(RKEY);console.log(JSON.stringify(rule));console.log("init_test_end")}function ocr_demo_test(){let img_base64=`iVBORw0KGgoAAAANSUhEUgAAAIAAAAAoBAMAAADEX+97AAAAG1BMVEXz+/4thQTa7N6QwIFFkyNeokKozqDB3b93sWHFR+MEAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABN0lEQVRIie2TQU+DQBCFt9vScvQpxR4xrcSjJCZ67JDGXsX+AdR4B3vpsSYm/m2HXaRLmuySepR3Gdidb/btDAjRq5dT96eCMlfBuzi1QLZUoZy2yz5sOvI+9iomaPEZ6nWnEtxqIyiM1RcAy44GNDhBXUjot/VVNweV1ah68FqWRyjKIOqAcyYF6rGcmpYnHzGt3fycNoMw0d3/THFu7hFSJ/8OXO6iTM8/KSg09obAzIHLO250LgQ0txOZSfgrV4Exdw98uGycJ0ErAeExZGhOmFHV9zHO6qVSj0MpLq7xZON56o++MjlsEgfVhbQWWME+xQX7J4V6zfi9A1Ly9rP1BvEXp+BbVJ/M77n+wfOIDVp51pZ4iBxvmj9AGrtvry6emwfKnVkW+ZRKd5ZNMvob36vXP9YPDmQki8QiCFAAAAAASUVORK5CYII=`;OcrApi.api=OCR_API;let code=OcrApi.classification(img_base64);log("测试验证码图片的ocr识别结果为:"+code)}function rsa_demo_test(){let t1=(new Date).getTime();let pkcs1_public=` +-----BEGIN RSA PUBLIC KEY----- +MEgCQQCrI0pQ/ERRpJ3Ou190XJedFq846nDYP52rOtXyDxlFK5D3p6JJu2RwsKwy +lsQ9xY0xYPpRZUZKMEeR7e9gmRNLAgMBAAE= +-----END RSA PUBLIC KEY----- +`.trim();let pkcs1_public_pem=` +MEgCQQCrI0pQ/ERRpJ3Ou190XJedFq846nDYP52rOtXyDxlFK5D3p6JJu2RwsKwy +lsQ9xY0xYPpRZUZKMEeR7e9gmRNLAgMBAAE= +`.trim();let pkcs8_public=` +-----BEGIN PUBLIC KEY----- +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKsjSlD8RFGknc67X3Rcl50WrzjqcNg/ +nas61fIPGUUrkPenokm7ZHCwrDKWxD3FjTFg+lFlRkowR5Ht72CZE0sCAwEAAQ== +-----END PUBLIC KEY-----`.trim();let pkcs8_public_pem=` +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKsjSlD8RFGknc67X3Rcl50WrzjqcNg/ +nas61fIPGUUrkPenokm7ZHCwrDKWxD3FjTFg+lFlRkowR5Ht72CZE0sCAwEAAQ== +`.trim();let pkcs1_private=` +-----BEGIN RSA PRIVATE KEY----- +MIIBOAIBAAJBAKsjSlD8RFGknc67X3Rcl50WrzjqcNg/nas61fIPGUUrkPenokm7 +ZHCwrDKWxD3FjTFg+lFlRkowR5Ht72CZE0sCAwEAAQI/b6OV1z65UokQaMvSeRXt +0Yv6wiYtduQI9qpq5nzy/ytaqsbBfClNTi/HifKPKxlRouWFkc518EQI8LBxoarJ +AiEA4DaONMplV8PQNa3TKn2F+SDEvLOCjdL0kHKdN90Ti28CIQDDZnTBaHgZwZbA +hS7Bbf5yvwjWMhO6Y7l04/Qm7R+35QIgPuQuqXIoUSD080mp1N5WyRW++atksIF+ +5lGv9e6GP/MCICnj8y/rl6Pd7tXDN6zcSeqLrfdNsREKhB3dKOCXgW9JAiAFYtFS +EJNBXVRTK42SNsZ2hJ/9xLwOwnH2epT8Q43s3Q== +-----END RSA PRIVATE KEY----- +`.trim();let pkcs8_private=` +-----BEGIN PRIVATE KEY----- +MIIBUgIBADANBgkqhkiG9w0BAQEFAASCATwwggE4AgEAAkEAqyNKUPxEUaSdzrtf +dFyXnRavOOpw2D+dqzrV8g8ZRSuQ96eiSbtkcLCsMpbEPcWNMWD6UWVGSjBHke3v +YJkTSwIDAQABAj9vo5XXPrlSiRBoy9J5Fe3Ri/rCJi125Aj2qmrmfPL/K1qqxsF8 +KU1OL8eJ8o8rGVGi5YWRznXwRAjwsHGhqskCIQDgNo40ymVXw9A1rdMqfYX5IMS8 +s4KN0vSQcp033ROLbwIhAMNmdMFoeBnBlsCFLsFt/nK/CNYyE7pjuXTj9CbtH7fl +AiA+5C6pcihRIPTzSanU3lbJFb75q2SwgX7mUa/17oY/8wIgKePzL+uXo93u1cM3 +rNxJ6out902xEQqEHd0o4JeBb0kCIAVi0VIQk0FdVFMrjZI2xnaEn/3EvA7CcfZ6 +lPxDjezd +-----END PRIVATE KEY----- +`.trim();let data=` +NodeRsa +这是node-rsa 现在修改集成在drpy里使用`.trim();let encryptedWithPublic=NODERSA.encryptRSAWithPublicKey(data,pkcs1_public,{outputEncoding:"base64",options:{environment:"browser",encryptionScheme:"pkcs1_oaep"}});console.log("公钥加密");console.log(encryptedWithPublic);let decryptedWithPrivate=NODERSA.decryptRSAWithPrivateKey(encryptedWithPublic,pkcs1_private,{options:{environment:"browser",encryptionScheme:"pkcs1_oaep"}});console.log("私钥解密");console.log(decryptedWithPrivate);let pkcs1_sha256_sign=NODERSA.sign("1",pkcs1_private,{outputEncoding:"base64",options:{environment:"browser",encryptionScheme:"pkcs1",signingScheme:"pkcs1-sha256"}});console.log("pkcs1_sha256_sign");console.log(pkcs1_sha256_sign);let pkcs1_sha256_sign_verify=NODERSA.verify("1","Oulx2QrgeipKYBtqEDqFb2s/+ndk2cGQxO4CkhU7iBM1vyNmmvqubpsmeoUuN3waGrYZLknSEdwBkfv0tUMpFQ==",pkcs1_private,{options:{environment:"browser",encryptionScheme:"pkcs1",signingScheme:"pkcs1-sha256"}});console.log("pkcs1_sha256_sign_verify");console.log(pkcs1_sha256_sign_verify);let pkcs1_oaep_sha256=NODERSA.encryptRSAWithPublicKey(data,`-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEA5KOq1gRNyllLNWKQy8sGpZE3Q1ULLSmzZw+eaAhj9lvqn7IsT1du +SYn08FfoOA2qMwtz+1O2l1mgzNoSVCyVpVabnTG+C9XKeZXAnJHd8aYA7l7Sxhdm +kte+iymYZ0ZBPzijo8938iugtVvqi9UgDmnY3u/NlQDqiL5BGqSxSTd/Sgmy3zD8 +PYzEa3wD9vehQ5fZZ45vKIq8GNVh2Z8+IGO85FF1OsN7+b2yGJa/FmDDNn0+HP+m +PfI+kYBqEVpo0Ztbc3UdxgFwGC8O1n8AQyriwHnSOtIiuBH62J/7qyC/3LEAApRb +Dd9YszqzmODjQUddZKHmvc638VW+azc0EwIDAQAB +-----END RSA PUBLIC KEY----- +`,{outputEncoding:"base64",options:{environment:"browser",encryptionScheme:{scheme:"pkcs1_oaep",hash:"sha256"}}});console.log("pkcs1_oaep_sha256");console.log(pkcs1_oaep_sha256);decryptedWithPrivate=NODERSA.decryptRSAWithPrivateKey("kSZesAAyYh2hdsQnYMdGqb6gKAzTauBKouvBzWcc4+F8RvGd0nwO6mVkUMVilPgUuNxjEauHayHiY8gI3Py45UI3+km0rSGyHrS6dHiHgCkMejXHieglYzAB0IxX3Jkm4z/66bdB/D+GFy0oct5fGCMI1UHPjEAYOsazJDa8lBFNbjiWFeb/qiZtIx3vGM7KYPAZzyRf/zPbbQ8zy9xOmRuOl5nnIxgo0Okp3KO/RIPO4GZOSBA8f2lx1UtNwwrXAMpcNavtoqHVcjJ/9lcotXYQFrn5b299pSIRf2gVm8ZJ31SK6Z8cc14nKtvgnmsgClDzIXJ1o1RcDK+knVAySg==",`-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA5KOq1gRNyllLNWKQy8sGpZE3Q1ULLSmzZw+eaAhj9lvqn7Is +T1duSYn08FfoOA2qMwtz+1O2l1mgzNoSVCyVpVabnTG+C9XKeZXAnJHd8aYA7l7S +xhdmkte+iymYZ0ZBPzijo8938iugtVvqi9UgDmnY3u/NlQDqiL5BGqSxSTd/Sgmy +3zD8PYzEa3wD9vehQ5fZZ45vKIq8GNVh2Z8+IGO85FF1OsN7+b2yGJa/FmDDNn0+ +HP+mPfI+kYBqEVpo0Ztbc3UdxgFwGC8O1n8AQyriwHnSOtIiuBH62J/7qyC/3LEA +ApRbDd9YszqzmODjQUddZKHmvc638VW+azc0EwIDAQABAoIBADZ/QGgUzInvsLp/ +zO2WbfYm39o/uhNAvk9RbLt1TIZbMFhyOpeKynHi3Swwd9xsfWX/U9zS/lGi/m31 +iKrhmaW4OA1G3vqpMcK7TBbFufYwUEaA+ZJX344euH8pIfdzyneMQ4z3Far2dS7l +QsmjuilVV2kEFadveXewiYoVOWCu00w6bN8wy2SIHlQn+kIL6HQhWz12iKKflIKu +eGRdzLHsKmBt6WbY1Wuhx7HU0fAKdlBDPxCHNlI+kybUYE9o5C2vJiaVM5wqJBgZ +8Dz8kt1QbLJ910JoLXkLVQ8uC8NJKQwFtqQjTGPnEq0+wbgz6Ij599rKZkwW/xq9 +l6KoUiECgYEA6Ah42tVdkNW047f03xVYXFH96RgorHRS36mR8Y+ONUq1fwKidovC +WjwVujt4OPf3l1W6iyn/F6cu/bsmvPrSc3HTN0B1V31QK4OjgetxQ2PSbTldH02J +NPzkt+v+cPxXpx/P5mgt7Weefw5txU547KubGrHUV5rBKFtIx9pj16MCgYEA/EF0 +o19+D24DZAPwlDS5VbEd7FStnwY4oQ5PqbuNOSbSJLMWU0AqzXcRokp8UTyCZ0X3 +ATkS1REq97kShCuR+npTR6a6DlY7sdpPI1SMLNajgB2tkx0EOzX+PfNIbHUd4jpJ +I0ZMAHv/OOtkzQHDaeTWBTrzsWm6/nTiykfduNECgYEA46AMD4HpPECqKAs66e5i +tI6q7JSKskObWVdcmQEfnSAhVOwcvPb2Ptda6UuV8S0xcwDi88rLOUUFUFzc79+P +vTkY38cYVi/VChsluDpk7ptqv0PbGu5Rf+3n4pZdEjI7OvR2W64wAAn67uIUxc7p +yiO/ET0K9rYWb6S9jXGtKMkCgYEA2kPAqoO7zZoBMQ7/oR0lp/HC1HRIbiqx4RlC +8Lgpb+QZPEwA6zPAVVvLVENi4d+bbcRp/xLlKpraNNJcJSSWAMbLPFoU7sbKjA87 +HnTPfRSTEA2d3Ibk3F7Rh8TzS3Ti0JZiJjVzGZAwu41iAMifzwaD8K6boUy80eNN +QH2CaaECgYBUsLYvC/MiYg3w+LGOONuQongoVUXjGqnw2bjVa9RK7lwRdXPUqJ51 +MpVO98IkoLvGSI/0sGNP3GKNhC+eMGjJAVwFyEuOn+JsmMv9Y9uStIVi5tIHIhKw +m7mp8il0kaftHdSxTbspG3tZ2fjIiFIZkLEOmRpd7ogWumgOajzUdA== +-----END RSA PRIVATE KEY-----`,{options:{environment:"browser",encryptionScheme:"pkcs1_oaep"}});console.log("decryptedWithPrivate");console.log(decryptedWithPrivate);(()=>{let key=new NODERSA.NodeRSA({b:1024});key.setOptions({encryptionScheme:"pkcs1"});let text=`你好drpy node-ras`;let encrypted=key.encrypt(text,"base64");console.log("encrypted: ",encrypted);const decrypted=key.decrypt(encrypted,"utf8");console.log("decrypted: ",decrypted)})();let t2=(new Date).getTime();console.log("rsa_demo_test 测试耗时:"+(t2-t1)+"毫秒")}function pre(){if(typeof rule.预处理==="string"&&rule.预处理&&rule.预处理.trim()){let code=rule.预处理.trim();console.log("执行预处理代码:"+code);if(code.startsWith("js:")){code=code.replace("js:","")}try{eval(code)}catch(e){console.log(`预处理执行失败:${e.message}`)}}}let rule={};const MOBILE_UA="Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36";const PC_UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36";const UA="Mozilla/5.0";const UC_UA="Mozilla/5.0 (Linux; U; Android 9; zh-CN; MI 9 Build/PKQ1.181121.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.5.5.1035 Mobile Safari/537.36";const IOS_UA="Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1";const RULE_CK="cookie";const CATE_EXCLUDE="首页|留言|APP|下载|资讯|新闻|动态";const TAB_EXCLUDE="猜你|喜欢|下载|剧情|榜|评论";const OCR_RETRY=3;const OCR_API="https://api.nn.ci/ocr/b64/text";if(typeof MY_URL==="undefined"){var MY_URL}var HOST;var RKEY;var fetch;var print;var log;var rule_fetch_params;var fetch_params;var oheaders;var _pdfh;var _pdfa;var _pd;const DOM_CHECK_ATTR=/(url|src|href|-original|-src|-play|-url|style)$/;const SPECIAL_URL=/^(ftp|magnet|thunder|ws):/;const NOADD_INDEX=/:eq|:lt|:gt|:first|:last|^body$|^#/;const URLJOIN_ATTR=/(url|src|href|-original|-src|-play|-url|style)$|^(data-|url-|src-)/;const SELECT_REGEX=/:eq|:lt|:gt|#/g;const SELECT_REGEX_A=/:eq|:lt|:gt/g;const $js={toString(func){let strfun=func.toString();return strfun.replace(/^\(\)(\s+)?=>(\s+)?\{/,"js:").replace(/\}$/,"")}};function window_b64(){let b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";let base64DecodeChars=new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1);function btoa(str){var out,i,len;var c1,c2,c3;len=str.length;i=0;out="";while(i>2);out+=b64map.charAt((c1&3)<<4);out+="==";break}c2=str.charCodeAt(i++);if(i==len){out+=b64map.charAt(c1>>2);out+=b64map.charAt((c1&3)<<4|(c2&240)>>4);out+=b64map.charAt((c2&15)<<2);out+="=";break}c3=str.charCodeAt(i++);out+=b64map.charAt(c1>>2);out+=b64map.charAt((c1&3)<<4|(c2&240)>>4);out+=b64map.charAt((c2&15)<<2|(c3&192)>>6);out+=b64map.charAt(c3&63)}return out}function atob(str){var c1,c2,c3,c4;var i,len,out;len=str.length;i=0;out="";while(i>4);do{c3=str.charCodeAt(i++)&255;if(c3==61)return out;c3=base64DecodeChars[c3]}while(i>2);do{c4=str.charCodeAt(i++)&255;if(c4==61)return out;c4=base64DecodeChars[c4]}while(ithis.length){return false}else{return this.indexOf(search,start)!==-1}}}if(!Array.prototype.includes){Object.defineProperty(Array.prototype,"includes",{value:function(searchElement,fromIndex){if(this==null){throw new TypeError('"this" is null or not defined')}var o=Object(this);var len=o.length>>>0;if(len===0){return false}var n=fromIndex|0;var k=Math.max(n>=0?n:len-Math.abs(n),0);while(k>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:out+=String.fromCharCode(c);break;case 12:case 13:char2=array[i++];out+=String.fromCharCode((c&31)<<6|char2&63);break;case 14:char2=array[i++];char3=array[i++];out+=String.fromCharCode((c&15)<<12|(char2&63)<<6|(char3&63)<<0);break}}return out}function gzip(str){let arr=zlib.gzip(str);return Buffer.from(arr,"utf-8").toString("base64")}function ungzip(b64Data){const binData=Buffer.from(b64Data,"base64");const data=zlib.ungzip(binData.buffer);return Buffer.from(data,"utf8").toString()}function encodeStr(input,encoding){encoding=encoding||"gbk";if(encoding.startsWith("gb")){input=gbkTool.encode(input)}return input}function decodeStr(input,encoding){encoding=encoding||"gbk";if(encoding.startsWith("gb")){input=gbkTool.decode(input)}return input}function getCryptoJS(){return'console.log("CryptoJS已装载");'}const RSA={cleanPEM:function(pem){pem=pem.replace(/-----BEGIN [A-Z0-9 ]+-----/g,"").replace(/-----END [A-Z0-9 ]+-----/g,"");pem=pem.replace(/\s/g,"");return pem},importPrivateKey:function(pem){const binaryDer=Uint8Array.from(Buffer.from(this.cleanPEM(pem),"base64"));const importedKey=crypto.subtle.importKey("pkcs8",binaryDer,{name:"RSA-PKCS1-v1_5",hash:"SHA-256"},false,["decrypt"]);return importedKey},importPublicKey:function(pem){const binaryDer=Uint8Array.from(Buffer.from(this.cleanPEM(pem),"base64"));const importedKey=crypto.subtle.importKey("spki",binaryDer,{name:"RSA-PKCS1-v1_5",hash:"SHA-256"},false,["encrypt"]);return importedKey},encryptMergedData:function(publicKey,data){const modulusLengthBytes=publicKey.algorithm.modulusLength+7>>3;const segmentLength=modulusLengthBytes-11;const dataBuffer=(new TextEncoder).encode(data);if(dataBuffer.length>segmentLength){const segments=[];for(let i=0;iacc+segment.length,0);let encryptedData=new Uint8Array(totalLength);let offset=0;for(const segment of encryptedSegments){encryptedData.set(segment,offset);offset+=segment.length}return encryptedData.slice(0,offset)}return crypto.subtle.encrypt({name:"RSA-PKCS1-v1_5"},publicKey,dataBuffer)},decryptMergedData:function(privateKey,mergedData){const segmentLength=privateKey.algorithm.modulusLength+7>>3;if(mergedData.length>segmentLength){const segments=[];for(let i=0;i{new_m3u8_body.push(it)})}}new_m3u8_body=new_m3u8_body.join("\n").trim();m3u8_text=[m3u8_start,new_m3u8_body,m3u8_end].join("\n").trim();return m3u8_text}function fixAdM3u8Ai(m3u8_url,headers){let ts=(new Date).getTime();let option=headers?{headers:headers}:{};function b(s1,s2){let i=0;while(iit.startsWith("#")?it:urljoin(m3u8_url,it)).join("\n");m3u8=m3u8.replace(/\n\n/gi,"\n");let last_url=m3u8.split("\n").slice(-1)[0];if(last_url.length<5){last_url=m3u8.split("\n").slice(-2)[0]}if(last_url.includes(".m3u8")&&last_url!==m3u8_url){m3u8_url=urljoin2(m3u8_url,last_url);log("嵌套的m3u8_url:"+m3u8_url);m3u8=request(m3u8_url,option)}let s=m3u8.trim().split("\n").filter(it=>it.trim()).join("\n");let ss=s.split("\n");if(m3u8_url.indexOf("ffzy")>0){let j=0,k1=0,m=0,n=0,t=0;let s2="";for(let i=0;i0){if(maxl>b(firststr,s)+1){if(secondstr.length<5)secondstr=s;kkk2++}else{maxl=b(firststr,s);kkk1++}}kk++;if(kk>=30)break}}if(kkk2>kkk1)firststr=secondstr;let firststrlen=firststr.length;let ml=Math.round(ss.length/2).toString().length;let maxc=0;let laststr=ss.toReversed().find(x=>{if(!x.startsWith("#")){let k=b(reverseString(firststr),reverseString(x));maxl=b(firststr,x);maxc++;if(firststrlen-maxl<=ml+k||maxc>10){return true}}return false});log("最后一条切片:"+laststr);let ad_urls=[];for(let i=0;i=end){return lists}let first=lists[start];let second=lists[end];if(key){try{first=first[key];second=second[key]}catch(e){}}if(option&&typeof option==="function"){try{first=option(first);second=option(second)}catch(e){}}first+="";second+="";if(first.match(/(\d+)/)&&second.match(/(\d+)/)){let num1=Number(first.match(/(\d+)/)[1]);let num2=Number(second.match(/(\d+)/)[1]);if(num1>num2){lists.reverse()}}return lists}let VODS=[];let VOD={};let TABS=[];let LISTS=[];function getQuery(url){try{if(url.indexOf("?")>-1){url=url.slice(url.indexOf("?")+1)}let arr=url.split("#")[0].split("&");const resObj={};arr.forEach(item=>{let arr1=item.split("=");let key=arr1[0];let value=arr1.slice(1).join("=");resObj[key]=value});return resObj}catch(err){log(`getQuery发生错误:${e.message}`);return{}}}function urljoin(fromPath,nowPath){fromPath=fromPath||"";nowPath=nowPath||"";return joinUrl(fromPath,nowPath)}var urljoin2=urljoin;const defaultParser={pdfh:pdfh,pdfa:pdfa,pd:pd};function pdfh2(html,parse){let html2=html;try{if(typeof html!=="string"){html2=html.rr(html.ele).toString()}}catch(e){print(`html对象转文本发生了错误:${e.message}`)}let result=defaultParser.pdfh(html2,parse);let option=parse.includes("&&")?parse.split("&&").slice(-1)[0]:parse.split(" ").slice(-1)[0];if(/style/.test(option.toLowerCase())&&/url\(/.test(result)){try{result=result.match(/url\((.*?)\)/)[1];result=result.replace(/^['|"](.*)['|"]$/,"$1")}catch(e){}}return result}function pdfa2(html,parse){let html2=html;try{if(typeof html!=="string"){html2=html.rr(html.ele).toString()}}catch(e){print(`html对象转文本发生了错误:${e.message}`)}return defaultParser.pdfa(html2,parse)}function pd2(html,parse,uri){let ret=pdfh2(html,parse);if(typeof uri==="undefined"||!uri){uri=""}if(DOM_CHECK_ATTR.test(parse)&&!SPECIAL_URL.test(ret)){if(/http/.test(ret)){ret=ret.slice(ret.indexOf("http"))}else{ret=urljoin(MY_URL,ret)}}return ret}const parseTags={jsp:{pdfh:pdfh2,pdfa:pdfa2,pd:pd2},json:{pdfh(html,parse){if(!parse||!parse.trim()){return""}if(typeof html==="string"){html=JSON.parse(html)}parse=parse.trim();if(!parse.startsWith("$.")){parse="$."+parse}parse=parse.split("||");for(let ps of parse){let ret=cheerio.jp(ps,html);if(Array.isArray(ret)){ret=ret[0]||""}else{ret=ret||""}if(ret&&typeof ret!=="string"){ret=ret.toString()}if(ret){return ret}}return""},pdfa(html,parse){if(!parse||!parse.trim()){return""}if(typeof html==="string"){html=JSON.parse(html)}parse=parse.trim();if(!parse.startsWith("$.")){parse="$."+parse}let ret=cheerio.jp(parse,html);if(Array.isArray(ret)&&Array.isArray(ret[0])&&ret.length===1){return ret[0]||[]}return ret||[]},pd(html,parse){let ret=parseTags.json.pdfh(html,parse);if(ret){return urljoin(MY_URL,ret)}return ret}},jq:{pdfh(html,parse){if(!html||!parse||!parse.trim()){return""}parse=parse.trim();let result=defaultParser.pdfh(html,parse);return result},pdfa(html,parse){if(!html||!parse||!parse.trim()){return[]}parse=parse.trim();let result=defaultParser.pdfa(html,parse);print(`pdfa解析${parse}=>${result.length}`);return result},pd(html,parse,base_url){if(!html||!parse||!parse.trim()){return""}parse=parse.trim();base_url=base_url||MY_URL;return defaultParser.pd(html,parse,base_url)}},getParse(p0){if(p0.startsWith("jsp:")){return this.jsp}else if(p0.startsWith("json:")){return this.json}else if(p0.startsWith("jq:")){return this.jq}else{return this.jq}}};const stringify=JSON.stringify;const jsp=parseTags.jsp;const jq=parseTags.jq;function readFile(filePath){filePath=filePath||"./uri.min.js";var fd=os.open(filePath);var buffer=new ArrayBuffer(1024);var len=os.read(fd,buffer,0,1024);console.log(len);let text=String.fromCharCode.apply(null,new Uint8Array(buffer));console.log(text);return text}function dealJson(html){try{html=html.trim();if(!(html.startsWith("{")&&html.endsWith("}")||html.startsWith("[")&&html.endsWith("]"))){html="{"+html.match(/.*?\{(.*)\}/m)[1]+"}"}}catch(e){}try{html=JSON.parse(html)}catch(e){}return html}var OcrApi={api:OCR_API,classification:function(img){let code="";try{log("通过drpy_ocr验证码接口过验证...");let html="";if(this.api.endsWith("drpy/text")){html=request(this.api,{data:{img:img},headers:{"User-Agent":PC_UA},method:"POST"},true)}else{html=post(this.api,{body:img})}code=html||""}catch(e){log(`OCR识别验证码发生错误:${e.message}`)}return code}};function verifyCode(url){let cnt=0;let host=getHome(url);let cookie="";while(cntit.toLowerCase()==="set-cookie");cookie=setCk?json[setCk].split(";")[0]:""}console.log("cookie:"+cookie);let img=json.body;let code=OcrApi.classification(img);console.log(`第${cnt+1}次验证码识别结果:${code}`);let submit_url=`${host}/index.php/ajax/verify_check?type=search&verify=${code}`;console.log(submit_url);let html=request(submit_url,{headers:{Cookie:cookie},method:"POST"});html=JSON.parse(html);if(html.msg==="ok"){console.log(`第${cnt+1}次验证码提交成功`);return cookie}else if(html.msg!=="ok"&&cnt+1>=OCR_RETRY){cookie=""}}catch(e){console.log(`第${cnt+1}次验证码提交失败:${e.message}`);if(cnt+1>=OCR_RETRY){cookie=""}}cnt+=1}return cookie}function setItem(k,v){local.set(RKEY,k,v);console.log(`规则${RKEY}设置${k} => ${v}`)}function getItem(k,v){return local.get(RKEY,k)||v}function clearItem(k){local.delete(RKEY,k)}function getHome(url){if(!url){return""}let tmp=url.split("//");url=tmp[0]+"//"+tmp[1].split("/")[0];try{url=decodeURIComponent(url)}catch(e){}return url}function buildUrl(url,obj){obj=obj||{};if(url.indexOf("?")<0){url+="?"}let param_list=[];let keys=Object.keys(obj);keys.forEach(it=>{param_list.push(it+"="+obj[it])});let prs=param_list.join("&");if(keys.length>0&&!url.endsWith("?")){url+="&"}url+=prs;return url}function $require(url){eval(request(url))}function keysToLowerCase(obj){return Object.keys(obj).reduce((result,key)=>{const newKey=key.toLowerCase();result[newKey]=obj[key];return result},{})}function buildQueryString(params){const queryArray=[];for(const key in params){if(params.hasOwnProperty(key)){let value=params[key];if(value===undefined||value===null){value=""}else{value=value.toString()}const encodedKey=encodeURIComponent(key);const encodedValue=encodeURIComponent(value);queryArray.push(encodedKey+"="+encodedValue)}}return queryArray.join("&")}function parseQueryString(query){const params={};query.split("&").forEach(function(part){const regex=/^(.*?)=(.*)/;const match=part.match(regex);if(match){const key=decodeURIComponent(match[1]);const value=decodeURIComponent(match[2]);params[key]=value}});return params}function encodeIfContainsSpecialChars(value){const specialChars=":/?#[]@!$'()*+,;=%";if(specialChars.split("").some(char=>value.includes(char))){return encodeURIComponent(value)}return value}function objectToQueryString(obj){const encoded=[];for(let key in obj){if(obj.hasOwnProperty(key)){encoded.push(encodeURIComponent(key)+"="+encodeIfContainsSpecialChars(obj[key]))}}return encoded.join("&")}function request(url,obj,ocr_flag){ocr_flag=ocr_flag||false;if(typeof obj==="undefined"||!obj||obj==={}){if(!fetch_params||!fetch_params.headers){let headers={"User-Agent":MOBILE_UA};if(rule.headers){Object.assign(headers,rule.headers)}if(!fetch_params){fetch_params={}}fetch_params.headers=headers}if(!fetch_params.headers.Referer){fetch_params.headers.Referer=getHome(url)}obj=fetch_params}else{let headers=obj.headers||{};let keys=Object.keys(headers).map(it=>it.toLowerCase());if(!keys.includes("user-agent")){headers["User-Agent"]=MOBILE_UA;if(typeof fetch_params==="object"&&fetch_params&&fetch_params.headers){let fetch_headers=keysToLowerCase(fetch_params.headers);if(fetch_headers["user-agent"]){headers["User-Agent"]=fetch_headers["user-agent"]}}}if(!keys.includes("referer")){headers["Referer"]=getHome(url)}obj.headers=headers}if(rule.encoding&&rule.encoding!=="utf-8"&&!ocr_flag){if(!obj.headers.hasOwnProperty("Content-Type")&&!obj.headers.hasOwnProperty("content-type")){obj.headers["Content-Type"]="text/html; charset="+rule.encoding}}if(typeof obj.body!="undefined"&&obj.body&&typeof obj.body==="string"){if(!obj.headers.hasOwnProperty("Content-Type")&&!obj.headers.hasOwnProperty("content-type")){obj.headers["Content-Type"]="application/x-www-form-urlencoded; charset="+rule.encoding}}else if(typeof obj.body!="undefined"&&obj.body&&typeof obj.body==="object"){obj.data=obj.body;delete obj.body}if(!url){return obj.withHeaders?"{}":""}if(obj.toBase64){obj.buffer=2;delete obj.toBase64}if(obj.redirect===false){obj.redirect=0}if(obj.headers.hasOwnProperty("Content-Type")||obj.headers.hasOwnProperty("content-type")){let _contentType=obj.headers["Content-Type"]||obj.headers["content-type"]||"";if(_contentType.includes("application/x-www-form-urlencoded")){log("custom body is application/x-www-form-urlencoded");if(typeof obj.body=="string"){let temp_obj=parseQueryString(obj.body);console.log(JSON.stringify(temp_obj))}}}console.log(JSON.stringify(obj.headers));console.log("request:"+url+`|method:${obj.method||"GET"}|body:${obj.body||""}`);let res=req(url,obj);let html=res.content||"";if(obj.withHeaders){let htmlWithHeaders=res.headers;htmlWithHeaders.body=html;return JSON.stringify(htmlWithHeaders)}else{return html}}function post(url,obj){obj=obj||{};obj.method="POST";return request(url,obj)}function reqCookie(url,obj,all_cookie){obj=obj||{};obj.withHeaders=true;all_cookie=all_cookie||false;let html=request(url,obj);let json=JSON.parse(html);let setCk=Object.keys(json).find(it=>it.toLowerCase()==="set-cookie");let cookie=setCk?json[setCk]:"";if(Array.isArray(cookie)){cookie=cookie.join(";")}if(!all_cookie){cookie=cookie.split(";")[0]}html=json.body;return{cookie:cookie,html:html}}fetch=request;print=function(data){data=data||"";if(typeof data=="object"&&Object.keys(data).length>0){try{data=JSON.stringify(data);console.log(data)}catch(e){console.log(typeof data+":"+data.length);return}}else if(typeof data=="object"&&Object.keys(data).length<1){console.log("null object")}else{console.log(data)}};log=print;function checkHtml(html,url,obj){if(/\?btwaf=/.test(html)){let btwaf=html.match(/btwaf(.*?)"/)[1];url=url.split("#")[0]+"?btwaf"+btwaf;print("宝塔验证访问链接:"+url);html=request(url,obj)}return html}function getCode(url,obj){let html=request(url,obj);html=checkHtml(html,url,obj);return html}function getHtml(url){let obj={};if(rule.headers){obj.headers=rule.headers}let cookie=getItem(RULE_CK,"");if(cookie){if(obj.headers&&!Object.keys(obj.headers).map(it=>it.toLowerCase()).includes("cookie")){log("历史无cookie,新增过验证后的cookie");obj.headers["Cookie"]=cookie}else if(obj.headers&&obj.headers.cookie&&obj.headers.cookie!==cookie){obj.headers["Cookie"]=cookie;log("历史有小写过期的cookie,更新过验证后的cookie")}else if(obj.headers&&obj.headers.Cookie&&obj.headers.Cookie!==cookie){obj.headers["Cookie"]=cookie;log("历史有大写过期的cookie,更新过验证后的cookie")}else if(!obj.headers){obj.headers={Cookie:cookie};log("历史无headers,更新过验证后的含cookie的headers")}}let html=getCode(url,obj);return html}function homeParse(homeObj){fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let classes=[];if(homeObj.class_name&&homeObj.class_url){let names=homeObj.class_name.split("&");let urls=homeObj.class_url.split("&");let cnt=Math.min(names.length,urls.length);for(let i=0;i0){classes=list}}}catch(e){console.log(e.message)}}else if(p.length>=3&&!is_json){try{let html=homeObj.home_html||getHtml(homeObj.MY_URL);if(html){homeHtmlCache=html;let list=_pdfa(html,p0);if(list&&list.length>0){list.forEach((it,idex)=>{try{let name=_pdfh(it,p[1]);if(homeObj.cate_exclude&&new RegExp(homeObj.cate_exclude).test(name)){return}let url=_pd(it,p[2]);if(p.length>3&&p[3]&&!homeObj.home_html){let exp=new RegExp(p[3]);url=url.match(exp)[1]}classes.push({type_id:url.trim(),type_name:name.trim()})}catch(e){console.log(`分类列表定位第${idex}个元素正常报错:${e.message}`)}})}}}catch(e){console.log(e.message)}}}}classes=classes.filter(it=>!homeObj.cate_exclude||!new RegExp(homeObj.cate_exclude).test(it.type_name));let resp={class:classes};if(homeObj.filter){resp.filters=homeObj.filter}console.log(JSON.stringify(resp));return JSON.stringify(resp)}function getPP(p,pn,pp,ppn){try{let ps=p[pn]==="*"&&pp.length>ppn?pp[ppn]:p[pn];return ps}catch(e){return""}}function homeVodParse(homeVodObj){fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let d=[];MY_URL=homeVodObj.homeUrl;console.log(MY_URL);let t1=(new Date).getTime();let p=homeVodObj.推荐;print("p:"+p);if(p==="*"&&rule.一级){p=rule.一级;homeVodObj.double=false}if(!p||typeof p!=="string"){return"{}"}p=p.trim();let pp=rule.一级?rule.一级.split(";"):[];if(p.startsWith("js:")){const TYPE="home";var input=MY_URL;HOST=rule.host;eval(p.replace("js:",""));d=VODS}else{p=p.split(";");if(!homeVodObj.double&&p.length<5){return"{}"}else if(homeVodObj.double&&p.length<6){return"{}"}let p0=getPP(p,0,pp,0);let _ps=parseTags.getParse(p0);_pdfa=_ps.pdfa;_pdfh=_ps.pdfh;_pd=_ps.pd;let is_json=p0.startsWith("json:");p0=p0.replace(/^(jsp:|json:|jq:)/,"");let html=homeHtmlCache||getHtml(MY_URL);homeHtmlCache=undefined;if(is_json){html=dealJson(html)}try{console.log("double:"+homeVodObj.double);if(homeVodObj.double){let items=_pdfa(html,p0);let p1=getPP(p,1,pp,0);let p2=getPP(p,2,pp,1);let p3=getPP(p,3,pp,2);let p4=getPP(p,4,pp,3);let p5=getPP(p,5,pp,4);let p6=getPP(p,6,pp,5);for(let item of items){let items2=_pdfa(item,p1);for(let item2 of items2){try{let title=_pdfh(item2,p2);let img="";try{img=_pd(item2,p3)}catch(e){}let desc="";try{desc=_pdfh(item2,p4)}catch(e){}let links=[];for(let _p5 of p5.split("+")){let link=!homeVodObj.detailUrl?_pd(item2,_p5,MY_URL):_pdfh(item2,_p5);links.push(link)}let content;if(p.length>6&&p[6]){content=_pdfh(item2,p6)}else{content=""}let vid=links.join("$");if(rule.二级==="*"){vid=vid+"@@"+title+"@@"+img}let vod={vod_name:title,vod_pic:img,vod_remarks:desc,vod_content:content,vod_id:vid};d.push(vod)}catch(e){console.log(`首页列表双层定位处理发生错误:${e.message}`)}}}}else{let items=_pdfa(html,p0);let p1=getPP(p,1,pp,1);let p2=getPP(p,2,pp,2);let p3=getPP(p,3,pp,3);let p4=getPP(p,4,pp,4);let p5=getPP(p,5,pp,5);for(let item of items){try{let title=_pdfh(item,p1);let img="";try{img=_pd(item,p2,MY_URL)}catch(e){}let desc="";try{desc=_pdfh(item,p3)}catch(e){}let links=[];for(let _p5 of p4.split("+")){let link=!homeVodObj.detailUrl?_pd(item,_p5,MY_URL):_pdfh(item,_p5);links.push(link)}let content;if(p.length>5&&p[5]){content=_pdfh(item,p5)}else{content=""}let vid=links.join("$");if(rule.二级==="*"){vid=vid+"@@"+title+"@@"+img}let vod={vod_name:title,vod_pic:img,vod_remarks:desc,vod_content:content,vod_id:vid};d.push(vod)}catch(e){console.log(`首页列表单层定位处理发生错误:${e.message}`)}}}}catch(e){}}let t2=(new Date).getTime();console.log("加载首页推荐耗时:"+(t2-t1)+"毫秒");if(rule.图片替换){if(rule.图片替换.startsWith("js:")){d.forEach(it=>{try{var input=it.vod_pic;eval(rule.图片替换.trim().replace("js:",""));it.vod_pic=input}catch(e){log(`图片:${it.vod_pic}替换错误:${e.message}`)}})}else if(rule.图片替换.includes("=>")){let replace_from=rule.图片替换.split("=>")[0];let replace_to=rule.图片替换.split("=>")[1];d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic.replace(replace_from,replace_to)}})}}if(rule.图片来源){d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic+rule.图片来源}})}if(d.length>0){print(d.slice(0,2))}return JSON.stringify({list:d})}function categoryParse(cateObj){fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let p=cateObj.一级;if(!p||typeof p!=="string"){return"{}"}let d=[];let url=cateObj.url.replaceAll("fyclass",cateObj.tid);if(cateObj.pg===1&&url.includes("[")&&url.includes("]")){url=url.split("[")[1].split("]")[0]}else if(cateObj.pg>1&&url.includes("[")&&url.includes("]")){url=url.split("[")[0]}if(rule.filter_url){if(!/fyfilter/.test(url)){if(!url.endsWith("&")&&!rule.filter_url.startsWith("&")){url+="&"}url+=rule.filter_url}else{url=url.replace("fyfilter",rule.filter_url)}url=url.replaceAll("fyclass",cateObj.tid);let fl=cateObj.filter?cateObj.extend:{};if(rule.filter_def&&typeof rule.filter_def==="object"){try{if(Object.keys(rule.filter_def).length>0&&rule.filter_def.hasOwnProperty(cateObj.tid)){let self_fl_def=rule.filter_def[cateObj.tid];if(self_fl_def&&typeof self_fl_def==="object"){let fl_def=JSON.parse(JSON.stringify(self_fl_def));fl=Object.assign(fl_def,fl)}}}catch(e){print(`合并不同分类对应的默认筛选出错:${e.message}`)}}let new_url;new_url=cheerio.jinja2(url,{fl:fl,fyclass:cateObj.tid});url=new_url}if(/fypage/.test(url)){if(url.includes("(")&&url.includes(")")){let url_rep=url.match(/.*?\((.*)\)/)[1];let cnt_page=url_rep.replaceAll("fypage",cateObj.pg);let cnt_pg=eval(cnt_page);url=url.replaceAll(url_rep,cnt_pg).replaceAll("(","").replaceAll(")","")}else{url=url.replaceAll("fypage",cateObj.pg)}}MY_URL=url;console.log(MY_URL);p=p.trim();const MY_CATE=cateObj.tid;if(p.startsWith("js:")){var MY_FL=cateObj.extend;const TYPE="cate";var input=MY_URL;const MY_PAGE=cateObj.pg;var desc="";eval(p.trim().replace("js:",""));d=VODS}else{p=p.split(";");if(p.length<5){return"{}"}let _ps=parseTags.getParse(p[0]);_pdfa=_ps.pdfa;_pdfh=_ps.pdfh;_pd=_ps.pd;let is_json=p[0].startsWith("json:");p[0]=p[0].replace(/^(jsp:|json:|jq:)/,"");try{let html=getHtml(MY_URL);if(html){if(is_json){html=dealJson(html)}let list=_pdfa(html,p[0]);list.forEach(it=>{let links=p[4].split("+").map(p4=>{return!rule.detailUrl?_pd(it,p4,MY_URL):_pdfh(it,p4)});let link=links.join("$");let vod_id=rule.detailUrl?MY_CATE+"$"+link:link;let vod_name=_pdfh(it,p[1]).replace(/\n|\t/g,"").trim();let vod_pic=_pd(it,p[2],MY_URL);if(rule.二级==="*"){vod_id=vod_id+"@@"+vod_name+"@@"+vod_pic}d.push({vod_id:vod_id,vod_name:vod_name,vod_pic:vod_pic,vod_remarks:_pdfh(it,p[3]).replace(/\n|\t/g,"").trim()})})}}catch(e){console.log(e.message)}}if(rule.图片替换){if(rule.图片替换.startsWith("js:")){d.forEach(it=>{try{var input=it.vod_pic;eval(rule.图片替换.trim().replace("js:",""));it.vod_pic=input}catch(e){log(`图片:${it.vod_pic}替换错误:${e.message}`)}})}else if(rule.图片替换.includes("=>")){let replace_from=rule.图片替换.split("=>")[0];let replace_to=rule.图片替换.split("=>")[1];d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic.replace(replace_from,replace_to)}})}}if(rule.图片来源){d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic+rule.图片来源}})}if(d.length>0){print(d.slice(0,2))}let pagecount=0;if(rule.pagecount&&typeof rule.pagecount==="object"&&rule.pagecount.hasOwnProperty(MY_CATE)){print(`MY_CATE:${MY_CATE},pagecount:${JSON.stringify(rule.pagecount)}`);pagecount=parseInt(rule.pagecount[MY_CATE])}let nodata={list:[{vod_name:"无数据,防无限请求",vod_id:"no_data",vod_remarks:"不要点,会崩的",vod_pic:"https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/404.jpg"}],total:1,pagecount:1,page:1,limit:1};let vod=d.length<1?JSON.stringify(nodata):JSON.stringify({page:parseInt(cateObj.pg),pagecount:pagecount||999,limit:20,total:999,list:d});return vod}function searchParse(searchObj){fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let d=[];if(!searchObj.searchUrl){return"{}"}if(rule.searchNoPage&&Number(searchObj.pg)>1){return"{}"}let p=searchObj.搜索==="*"&&rule.一级?rule.一级:searchObj.搜索;if(!p||typeof p!=="string"){return"{}"}p=p.trim();let pp=rule.一级?rule.一级.split(";"):[];let url=searchObj.searchUrl.replaceAll("**",searchObj.wd);if(searchObj.pg===1&&url.includes("[")&&url.includes("]")&&!url.includes("#")){url=url.split("[")[1].split("]")[0]}else if(searchObj.pg>1&&url.includes("[")&&url.includes("]")&&!url.includes("#")){url=url.split("[")[0]}if(/fypage/.test(url)){if(url.includes("(")&&url.includes(")")){let url_rep=url.match(/.*?\((.*)\)/)[1];let cnt_page=url_rep.replaceAll("fypage",searchObj.pg);let cnt_pg=eval(cnt_page);url=url.replaceAll(url_rep,cnt_pg).replaceAll("(","").replaceAll(")","")}else{url=url.replaceAll("fypage",searchObj.pg)}}MY_URL=url;console.log(MY_URL);if(p.startsWith("js:")){const TYPE="search";const MY_PAGE=searchObj.pg;const KEY=searchObj.wd;var input=MY_URL;var detailUrl=rule.detailUrl||"";eval(p.trim().replace("js:",""));d=VODS}else{p=p.split(";");if(p.length<5){return"{}"}let p0=getPP(p,0,pp,0);let _ps=parseTags.getParse(p0);_pdfa=_ps.pdfa;_pdfh=_ps.pdfh;_pd=_ps.pd;let is_json=p0.startsWith("json:");p0=p0.replace(/^(jsp:|json:|jq:)/,"");try{let req_method=MY_URL.split(";").length>1?MY_URL.split(";")[1].toLowerCase():"get";let html;if(req_method==="post"){let rurls=MY_URL.split(";")[0].split("#");let rurl=rurls[0];let params=rurls.length>1?rurls[1]:"";print(`post=》rurl:${rurl},params:${params}`);let _fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let postData={body:params};Object.assign(_fetch_params,postData);html=post(rurl,_fetch_params)}else if(req_method==="postjson"){let rurls=MY_URL.split(";")[0].split("#");let rurl=rurls[0];let params=rurls.length>1?rurls[1]:"";print(`postjson-》rurl:${rurl},params:${params}`);try{params=JSON.parse(params)}catch(e){params="{}"}let _fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let postData={body:params};Object.assign(_fetch_params,postData);html=post(rurl,_fetch_params)}else{html=getHtml(MY_URL)}if(html){let search_tag=rule.搜索验证标识||"系统安全验证|输入验证码";if(new RegExp(search_tag).test(html)){let cookie=verifyCode(MY_URL);if(cookie){console.log(`本次成功过验证,cookie:${cookie}`);setItem(RULE_CK,cookie)}else{console.log(`本次自动过搜索验证失败,cookie:${cookie}`)}html=getHtml(MY_URL)}if(!html.includes(searchObj.wd)){console.log("搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码");console.log(html)}if(is_json){html=dealJson(html)}let list=_pdfa(html,p0);let p1=getPP(p,1,pp,1);let p2=getPP(p,2,pp,2);let p3=getPP(p,3,pp,3);let p4=getPP(p,4,pp,4);let p5=getPP(p,5,pp,5);list.forEach(it=>{let links=p4.split("+").map(_p4=>{return!rule.detailUrl?_pd(it,_p4,MY_URL):_pdfh(it,_p4)});let link=links.join("$");let content;if(p.length>5&&p[5]){content=_pdfh(it,p5)}else{content=""}let vod_id=link;let vod_name=_pdfh(it,p1).replace(/\n|\t/g,"").trim();let vod_pic=_pd(it,p2,MY_URL);if(rule.二级==="*"){vod_id=vod_id+"@@"+vod_name+"@@"+vod_pic}let ob={vod_id:vod_id,vod_name:vod_name,vod_pic:vod_pic,vod_remarks:_pdfh(it,p3).replace(/\n|\t/g,"").trim(),vod_content:content.replace(/\n|\t/g,"").trim()};d.push(ob)})}}catch(e){print(`搜索发生错误:${e.message}`);return"{}"}}if(rule.图片替换){if(rule.图片替换.startsWith("js:")){d.forEach(it=>{try{var input=it.vod_pic;eval(rule.图片替换.trim().replace("js:",""));it.vod_pic=input}catch(e){log(`图片:${it.vod_pic}替换错误:${e.message}`)}})}else if(rule.图片替换.includes("=>")){let replace_from=rule.图片替换.split("=>")[0];let replace_to=rule.图片替换.split("=>")[1];d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic.replace(replace_from,replace_to)}})}}if(rule.图片来源){d.forEach(it=>{if(it.vod_pic&&it.vod_pic.startsWith("http")){it.vod_pic=it.vod_pic+rule.图片来源}})}return JSON.stringify({page:parseInt(searchObj.pg),pagecount:10,limit:20,total:100,list:d})}function detailParse(detailObj){let t1=(new Date).getTime();fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));let orId=detailObj.orId;let vod_name="片名";let vod_pic="";let vod_id=orId;if(rule.二级==="*"){let extra=orId.split("@@");vod_name=extra.length>1?extra[1]:vod_name;vod_pic=extra.length>2?extra[2]:vod_pic}let vod={vod_id:vod_id,vod_name:vod_name,vod_pic:vod_pic,type_name:"类型",vod_year:"年份",vod_area:"地区",vod_remarks:"更新信息",vod_actor:"主演",vod_director:"导演",vod_content:"简介"};let p=detailObj.二级;let url=detailObj.url;let detailUrl=detailObj.detailUrl;let fyclass=detailObj.fyclass;let tab_exclude=detailObj.tab_exclude;let html=detailObj.html||"";MY_URL=url;if(detailObj.二级访问前){try{print(`尝试在二级访问前执行代码:${detailObj.二级访问前}`);eval(detailObj.二级访问前.trim().replace("js:",""))}catch(e){print(`二级访问前执行代码出现错误:${e.message}`)}}if(p==="*"){vod.vod_play_from="道长在线";vod.vod_remarks=detailUrl;vod.vod_actor="没有二级,只有一级链接直接嗅探播放";vod.vod_content=MY_URL;vod.vod_play_url="嗅探播放$"+MY_URL.split("@@")[0]}else if(typeof p==="string"&&p.trim().startsWith("js:")){const TYPE="detail";var input=MY_URL;var play_url="";eval(p.trim().replace("js:",""));vod=VOD;console.log(JSON.stringify(vod))}else if(p&&typeof p==="object"){let tt1=(new Date).getTime();if(!html){html=getHtml(MY_URL)}print(`二级${MY_URL}仅获取源码耗时:${(new Date).getTime()-tt1}毫秒`);let _ps;if(p.is_json){print("二级是json");_ps=parseTags.json;html=dealJson(html)}else if(p.is_jsp){print("二级是jsp");_ps=parseTags.jsp}else if(p.is_jq){print("二级是jq");_ps=parseTags.jq}else{print("二级默认jq");_ps=parseTags.jq}let tt2=(new Date).getTime();print(`二级${MY_URL}获取并装载源码耗时:${tt2-tt1}毫秒`);_pdfa=_ps.pdfa;_pdfh=_ps.pdfh;_pd=_ps.pd;if(p.title){let p1=p.title.split(";");vod.vod_name=_pdfh(html,p1[0]).replace(/\n|\t/g,"").trim();let type_name=p1.length>1?_pdfh(html,p1[1]).replace(/\n|\t/g,"").replace(/ /g,"").trim():"";vod.type_name=type_name||vod.type_name}if(p.desc){try{let p1=p.desc.split(";");vod.vod_remarks=_pdfh(html,p1[0]).replace(/\n|\t/g,"").trim();vod.vod_year=p1.length>1?_pdfh(html,p1[1]).replace(/\n|\t/g,"").trim():"";vod.vod_area=p1.length>2?_pdfh(html,p1[2]).replace(/\n|\t/g,"").trim():"";vod.vod_actor=p1.length>3?_pdfh(html,p1[3]).replace(/\n|\t/g,"").trim():"";vod.vod_director=p1.length>4?_pdfh(html,p1[4]).replace(/\n|\t/g,"").trim():""}catch(e){}}if(p.content){try{let p1=p.content.split(";");vod.vod_content=_pdfh(html,p1[0]).replace(/\n|\t/g,"").trim()}catch(e){}}if(p.img){try{let p1=p.img.split(";");vod.vod_pic=_pd(html,p1[0],MY_URL)}catch(e){}}let vod_play_from="$$$";let playFrom=[];if(p.重定向&&p.重定向.startsWith("js:")){print("开始执行重定向代码:"+p.重定向);html=eval(p.重定向.replace("js:",""))}if(p.tabs){if(p.tabs.startsWith("js:")){print("开始执行tabs代码:"+p.tabs);var input=MY_URL;eval(p.tabs.replace("js:",""));playFrom=TABS}else{let p_tab=p.tabs.split(";")[0];let vHeader=_pdfa(html,p_tab);console.log(vHeader.length);let tab_text=p.tab_text||"body&&Text";let new_map={};for(let v of vHeader){let v_title=_pdfh(v,tab_text).trim();if(!v_title){v_title="线路空"}console.log(v_title);if(tab_exclude&&new RegExp(tab_exclude).test(v_title)){continue}if(!new_map.hasOwnProperty(v_title)){new_map[v_title]=1}else{new_map[v_title]+=1}if(new_map[v_title]>1){v_title+=Number(new_map[v_title]-1)}playFrom.push(v_title)}}console.log(JSON.stringify(playFrom))}else{playFrom=["道长在线"]}vod.vod_play_from=playFrom.join(vod_play_from);let vod_play_url="$$$";let vod_tab_list=[];if(p.lists){if(p.lists.startsWith("js:")){print("开始执行lists代码:"+p.lists);try{var input=MY_URL;var play_url="";eval(p.lists.replace("js:",""));for(let i in LISTS){if(LISTS.hasOwnProperty(i)){try{LISTS[i]=LISTS[i].map(it=>it.split("$").slice(0,2).join("$"))}catch(e){print(`格式化LISTS发生错误:${e.message}`)}}}vod_play_url=LISTS.map(it=>it.join("#")).join(vod_play_url)}catch(e){print(`js执行lists: 发生错误:${e.message}`)}}else{let list_text=p.list_text||"body&&Text";let list_url=p.list_url||"a&&href";let list_url_prefix=p.list_url_prefix||"";let is_tab_js=p.tabs.trim().startsWith("js:");for(let i=0;i1&&!is_tab_js?p.tabs.split(";")[1]:"";let p1=p.lists.replaceAll("#idv",tab_name).replaceAll("#id",i);tab_ext=tab_ext.replaceAll("#idv",tab_name).replaceAll("#id",i);let tabName=tab_ext?_pdfh(html,tab_ext):tab_name;console.log(tabName);let new_vod_list=[];let tt1=(new Date).getTime();if(typeof pdfl==="function"){new_vod_list=pdfl(html,p1,list_text,list_url,MY_URL);if(list_url_prefix){new_vod_list=new_vod_list.map(it=>it.split("$")[0]+"$"+list_url_prefix+it.split("$").slice(1).join("$"))}}else{let vodList=[];try{vodList=_pdfa(html,p1);console.log("len(vodList):"+vodList.length)}catch(e){}for(let i=0;i0){new_vod_list=forceOrder(new_vod_list,"",x=>x.split("$")[0]);console.log(`drpy影响性能代码共计列表数循环次数:${new_vod_list.length},耗时:${(new Date).getTime()-tt1}毫秒`)}let vlist=new_vod_list.join("#");vod_tab_list.push(vlist)}vod_play_url=vod_tab_list.join(vod_play_url)}}vod.vod_play_url=vod_play_url}if(rule.图片替换&&rule.图片替换.includes("=>")){let replace_from=rule.图片替换.split("=>")[0];let replace_to=rule.图片替换.split("=>")[1];vod.vod_pic=vod.vod_pic.replace(replace_from,replace_to)}if(rule.图片来源&&vod.vod_pic&&vod.vod_pic.startsWith("http")){vod.vod_pic=vod.vod_pic+rule.图片来源}if(!vod.vod_id||vod_id.includes("$")&&vod.vod_id!==vod_id){vod.vod_id=vod_id}let t2=(new Date).getTime();console.log(`加载二级界面${MY_URL}耗时:${t2-t1}毫秒`);try{vod=vodDeal(vod)}catch(e){console.log(`vodDeal发生错误:${e.message}`)}return JSON.stringify({list:[vod]})}function get_tab_index(vod){let obj={};vod.vod_play_from.split("$$$").forEach((it,index)=>{obj[it]=index});return obj}function vodDeal(vod){let vod_play_from=vod.vod_play_from.split("$$$");let vod_play_url=vod.vod_play_url.split("$$$");let tab_removed_list=vod_play_from;let tab_ordered_list=vod_play_from;let tab_renamed_list=vod_play_from;let tab_list=vod_play_from;let play_ordered_list=vod_play_url;if(rule.tab_remove&&rule.tab_remove.length>0||rule.tab_order&&rule.tab_order.length>0){let tab_index_dict=get_tab_index(vod);if(rule.tab_remove&&rule.tab_remove.length>0){tab_removed_list=vod_play_from.filter(it=>!rule.tab_remove.includes(it));tab_list=tab_removed_list}if(rule.tab_order&&rule.tab_order.length>0){let tab_order=rule.tab_order;tab_ordered_list=tab_removed_list.sort((a,b)=>{const getOrderIndex=(tabName,orderRules)=>{for(let i=0;ivod_play_url[tab_index_dict[it]])}if(rule.tab_rename&&typeof rule.tab_rename==="object"&Object.keys(rule.tab_rename).length>0){tab_renamed_list=tab_list.map(it=>rule.tab_rename[it]||it);tab_list=tab_renamed_list}vod.vod_play_from=tab_list.join("$$$");vod.vod_play_url=play_ordered_list.join("$$$");return vod}function tellIsJx(url){try{let is_vip=!/\.(m3u8|mp4|m4a)$/.test(url.split("?")[0])&&是否正版(url);return is_vip?1:0}catch(e){return 1}}function playParse(playObj){fetch_params=JSON.parse(JSON.stringify(rule_fetch_params));MY_URL=playObj.url;var MY_FLAG=playObj.flag;if(!/http/.test(MY_URL)){try{MY_URL=base64Decode(MY_URL)}catch(e){}}MY_URL=decodeURIComponent(MY_URL);var input=MY_URL;var flag=MY_FLAG;let common_play={parse:SPECIAL_URL.test(input)||/^(push:)/.test(input)?0:1,url:input,flag:flag,jx:tellIsJx(input)};let lazy_play;if(!rule.play_parse||!rule.lazy){lazy_play=common_play}else if(rule.play_parse&&rule.lazy&&typeof rule.lazy==="string"){try{let lazy_code=rule.lazy.trim();if(lazy_code.startsWith("js:")){lazy_code=lazy_code.replace("js:","").trim()}print("开始执行js免嗅=>"+lazy_code);eval(lazy_code);lazy_play=typeof input==="object"?input:{parse:SPECIAL_URL.test(input)||/^(push:)/.test(input)?0:1,jx:tellIsJx(input),url:input}}catch(e){print(`js免嗅错误:${e.message}`);lazy_play=common_play}}else{lazy_play=common_play}if(Array.isArray(rule.play_json)&&rule.play_json.length>0){let web_url=lazy_play.url;for(let pjson of rule.play_json){if(pjson.re&&(pjson.re==="*"||web_url.match(new RegExp(pjson.re)))){if(pjson.json&&typeof pjson.json==="object"){let base_json=pjson.json;lazy_play=Object.assign(lazy_play,base_json);break}}}}else if(rule.play_json&&!Array.isArray(rule.play_json)){let base_json={jx:1,parse:1};lazy_play=Object.assign(lazy_play,base_json)}else if(!rule.play_json){let base_json={jx:0,parse:1};lazy_play=Object.assign(lazy_play,base_json)}console.log(JSON.stringify(lazy_play));return JSON.stringify(lazy_play)}function proxyParse(proxyObj){var input=proxyObj.params;if(proxyObj.proxy_rule){log("准备执行本地代理规则:\n"+proxyObj.proxy_rule);try{eval(proxyObj.proxy_rule);if(input&&input!==proxyObj.params&&Array.isArray(input)&&input.length>=3){return input}else{return[404,"text/plain","Not Found"]}}catch(e){return[500,"text/plain","代理规则错误:"+e.message]}}else{return[404,"text/plain","Not Found"]}}function isVideoParse(isVideoObj){var input=isVideoObj.url;if(!isVideoObj.t){let re_matcher=new RegExp(isVideoObj.isVideo,"i");return re_matcher.test(input)}else{try{eval(isVideoObj.isVideo);if(typeof input==="boolean"){return input}else{return false}}catch(e){log(`执行嗅探规则发生错误:${e.message}`);return false}}}function removeHeader(content,options={}){const{mode="header-only",fileType}=options;const COMMENT_CONFIG={".js":{start:"/*",end:"*/",regex:/^\s*\/\*([\s\S]*?)\*\/\s*/,headerRegex:/@header\(([\s\S]*?)\)/,topCommentsRegex:/^(\s*(\/\/[^\n]*\n|\/\*[\s\S]*?\*\/)\s*)+/},".py":{start:'"""',end:'"""',regex:/^\s*"""([\s\S]*?)"""\s*/,headerRegex:/@header\(([\s\S]*?)\)/,topCommentsRegex:/^(\s*(#[^\n]*\n|'''[\s\S]*?'''|"""[\s\S]*?""")\s*)+/}};if(!fileType)throw new Error("fileType option is required");const ext=fileType.startsWith(".")?fileType:`.${fileType}`;const config=COMMENT_CONFIG[ext];if(!config)throw new Error(`Unsupported file type: ${ext}`);if(mode==="top-comments"){const match=content.match(config.topCommentsRegex);if(match){return content.substring(match[0].length).trim()}return content.trim()}const match=content.match(config.regex);if(!match)return content.trim();let[fullComment,innerContent]=match;if(config.headerRegex.test(innerContent)){innerContent=innerContent.replace(config.headerRegex,"");const cleanedInner=innerContent.split("\n").filter(line=>line.trim().length>0).join("\n");if(!cleanedInner.trim()){return content.replace(fullComment,"").trim()}else{const newComment=`${config.start}${cleanedInner}${config.end}`;return content.replace(fullComment,newComment).trim()}}return content.trim()}function getOriginalJs(js_code){let current_match=/var rule|function|let |var |const|class Rule|async|this\./;if(current_match.test(js_code)){return js_code}js_code=removeHeader(js_code,{mode:"top-comments",fileType:".js"});let rsa_private_key="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqin/jUpqM6+fgYP/oMqj9zcdHMM0mEZXLeTyixIJWP53lzJV2N2E3OP6BBpUmq2O1a9aLnTIbADBaTulTNiOnVGoNG58umBnupnbmmF8iARbDp2mTzdMMeEgLdrfXS6Y3VvazKYALP8EhEQykQVarexR78vRq7ltY3quXx7cgI0ROfZz5Sw3UOLQJ+VoWmwIxu9AMEZLVzFDQN93hzuzs3tNyHK6xspBGB7zGbwCg+TKi0JeqPDrXxYUpAz1cQ/MO+Da0WgvkXnvrry8NQROHejdLVOAslgr6vYthH9bKbsGyNY3H+P12kcxo9RAcVveONnZbcMyxjtF5dWblaernAgMBAAECggEAGdEHlSEPFmAr5PKqKrtoi6tYDHXdyHKHC5tZy4YV+Pp+a6gxxAiUJejx1hRqBcWSPYeKne35BM9dgn5JofgjI5SKzVsuGL6bxl3ayAOu+xXRHWM9f0t8NHoM5fdd0zC3g88dX3fb01geY2QSVtcxSJpEOpNH3twgZe6naT2pgiq1S4okpkpldJPo5GYWGKMCHSLnKGyhwS76gF8bTPLoay9Jxk70uv6BDUMlA4ICENjmsYtd3oirWwLwYMEJbSFMlyJvB7hjOjR/4RpT4FPnlSsIpuRtkCYXD4jdhxGlvpXREw97UF2wwnEUnfgiZJ2FT/MWmvGGoaV/CfboLsLZuQKBgQDTNZdJrs8dbijynHZuuRwvXvwC03GDpEJO6c1tbZ1s9wjRyOZjBbQFRjDgFeWs9/T1aNBLUrgsQL9c9nzgUziXjr1Nmu52I0Mwxi13Km/q3mT+aQfdgNdu6ojsI5apQQHnN/9yMhF6sNHg63YOpH+b+1bGRCtr1XubuLlumKKscwKBgQDOtQ2lQjMtwsqJmyiyRLiUOChtvQ5XI7B2mhKCGi8kZ+WEAbNQcmThPesVzW+puER6D4Ar4hgsh9gCeuTaOzbRfZ+RLn3Aksu2WJEzfs6UrGvm6DU1INn0z/tPYRAwPX7sxoZZGxqML/z+/yQdf2DREoPdClcDa2Lmf1KpHdB+vQKBgBXFCVHz7a8n4pqXG/HvrIMJdEpKRwH9lUQS/zSPPtGzaLpOzchZFyQQBwuh1imM6Te+VPHeldMh3VeUpGxux39/m+160adlnRBS7O7CdgSsZZZ/dusS06HAFNraFDZf1/VgJTk9BeYygX+AZYu+0tReBKSs9BjKSVJUqPBIVUQXAoGBAJcZ7J6oVMcXxHxwqoAeEhtvLcaCU9BJK36XQ/5M67ceJ72mjJC6/plUbNukMAMNyyi62gO6I9exearecRpB/OGIhjNXm99Ar59dAM9228X8gGfryLFMkWcO/fNZzb6lxXmJ6b2LPY3KqpMwqRLTAU/zy+ax30eFoWdDHYa4X6e1AoGAfa8asVGOJ8GL9dlWufEeFkDEDKO9ww5GdnpN+wqLwePWqeJhWCHad7bge6SnlylJp5aZXl1+YaBTtOskC4Whq9TP2J+dNIgxsaF5EFZQJr8Xv+lY9lu0CruYOh9nTNF9x3nubxJgaSid/7yRPfAGnsJRiknB5bsrCvgsFQFjJVs=";let decode_content="";function aes_decrypt(data){const keyHex="686A64686E780A0A0A0A0A0A0A0A0A0A";const ivHex="647A797964730A0A0A0A0A0A0A0A0A0A";const keyArray=new Uint8Array(Buffer.from(keyHex,"hex"));const ivArray=new Uint8Array(Buffer.from(ivHex,"hex"));const encryptedArray=new Uint8Array(Buffer.from(data,"base64"));const key=crypto.subtle.importKey("raw",keyArray,{name:"AES-CBC"},false,["decrypt"]);try{const decryptedArray=crypto.subtle.decrypt({name:"AES-CBC",iv:ivArray},key,encryptedArray);const decryptedString=(new TextDecoder).decode(decryptedArray);return decryptedString}catch(e){console.error("解密失败:",e);return null}}let error_log=false;function logger(text){if(error_log){log(text)}}let decode_funcs=[text=>{try{return ungzip(text)}catch(e){logger("非gzip加密");return""}},text=>{try{return base64Decode(text)}catch(e){logger("非b64加密");return""}},text=>{try{return aes_decrypt(text)}catch(e){logger("非aes加密");return""}},text=>{try{return RSA.decode(text,rsa_private_key,null)}catch(e){logger("非rsa加密");return""}}];let func_index=0;while(!current_match.test(decode_content)){decode_content=decode_funcs[func_index](js_code);func_index++;if(func_index>=decode_funcs.length){break}}return decode_content}function runMain(main_func_code,arg){let mainFunc=function(){return""};try{eval(main_func_code+"\nmainFunc=main;");return mainFunc(arg)}catch(e){log(`执行main_funct发生了错误:${e.message}`);return""}}function init(ext){console.log("init");rule={};rule_fetch_params={};fetch_params=null;try{let muban=模板.getMubans();if(typeof ext=="object"){rule=ext}else if(typeof ext=="string"){let is_file=ext.startsWith("file://");if(ext.startsWith("http")||is_file){let query=getQuery(ext);if(is_file){ext=ext.split("?")[0]}let js=request(ext,{method:"GET"});if(js){js=getOriginalJs(js);eval("(function(){"+js.replace("var rule","rule")+"})()")}if(query.type==="url"&&query.params){if(is_file&&/^http/.test(query.params)){rule.params=query.params}else{rule.params=urljoin(ext,query.params)}}else if(query.params){rule.params=query.params}}else{ext=getOriginalJs(ext);eval("(function(){"+ext.replace("var rule","rule")+"})()")}}else{console.log(`规则加载失败,不支持的规则类型:${typeof ext}`);return}rule.host=(rule.host||"").rstrip("/");HOST=rule.host;if(rule.hostJs){console.log(`检测到hostJs,准备执行...`);try{eval(rule.hostJs);rule.host=HOST.rstrip("/")}catch(e){console.log(`执行${rule.hostJs}获取host发生错误:${e.message}`)}}if(rule["模板"]==="自动"){try{let host_headers=rule["headers"]||{};let host_html=getCode(HOST,{headers:host_headers});let match_muban="";let muban_keys=Object.keys(muban).filter(it=>!/默认|短视2|采集1/.test(it));for(let muban_key of muban_keys){try{let host_data=JSON.parse(home({},host_html,muban[muban_key].class_parse));if(host_data.class&&host_data.class.length>0){match_muban=muban_key;console.log(`自动匹配模板:【${muban_key}】`);break}}catch(e){console.log(`自动匹配模板:【${muban_key}】错误:${e.message}`)}}if(match_muban){muban["自动"]=muban[match_muban];if(rule["模板修改"]&&rule["模板修改"].startsWith("js:")){eval(rule["模板修改"].replace("js:","").trim())}}else{delete rule["模板"]}}catch(e){delete rule["模板"]}}if(rule.模板&&muban.hasOwnProperty(rule.模板)){print("继承模板:"+rule.模板);rule=Object.assign(muban[rule.模板],rule)}let rule_cate_excludes=(rule.cate_exclude||"").split("|").filter(it=>it.trim());let rule_tab_excludes=(rule.tab_exclude||"").split("|").filter(it=>it.trim());rule_cate_excludes=rule_cate_excludes.concat(CATE_EXCLUDE.split("|").filter(it=>it.trim()));rule_tab_excludes=rule_tab_excludes.concat(TAB_EXCLUDE.split("|").filter(it=>it.trim()));rule.cate_exclude=rule_cate_excludes.join("|");rule.tab_exclude=rule_tab_excludes.join("|");rule.类型=rule.类型||"影视";rule.url=rule.url||"";rule.double=rule.double||false;rule.homeUrl=rule.homeUrl||"";rule.detailUrl=rule.detailUrl||"";rule.searchUrl=rule.searchUrl||"";rule.homeUrl=rule.host&&rule.homeUrl?urljoin(rule.host,rule.homeUrl):rule.homeUrl||rule.host;rule.homeUrl=cheerio.jinja2(rule.homeUrl,{rule:rule});rule.detailUrl=rule.host&&rule.detailUrl?urljoin(rule.host,rule.detailUrl):rule.detailUrl;rule.二级访问前=rule.二级访问前||"";if(rule.url.includes("[")&&rule.url.includes("]")){let u1=rule.url.split("[")[0];let u2=rule.url.split("[")[1].split("]")[0];rule.url=rule.host&&rule.url?urljoin(rule.host,u1)+"["+urljoin(rule.host,u2)+"]":rule.url}else{rule.url=rule.host&&rule.url?urljoin(rule.host,rule.url):rule.url}if(rule.searchUrl.includes("[")&&rule.searchUrl.includes("]")&&!rule.searchUrl.includes("#")){let u1=rule.searchUrl.split("[")[0];let u2=rule.searchUrl.split("[")[1].split("]")[0];rule.searchUrl=rule.host&&rule.searchUrl?urljoin(rule.host,u1)+"["+urljoin(rule.host,u2)+"]":rule.searchUrl}else{rule.searchUrl=rule.host&&rule.searchUrl?urljoin(rule.host,rule.searchUrl):rule.searchUrl}rule.timeout=rule.timeout||5e3;rule.encoding=rule.编码||rule.encoding||"utf-8";rule.search_encoding=rule.搜索编码||rule.search_encoding||"";rule.图片来源=rule.图片来源||"";rule.图片替换=rule.图片替换||"";rule.play_json=rule.hasOwnProperty("play_json")?rule.play_json:[];rule.pagecount=rule.hasOwnProperty("pagecount")?rule.pagecount:{};rule.proxy_rule=rule.hasOwnProperty("proxy_rule")?rule.proxy_rule:"";if(!rule.hasOwnProperty("sniffer")){rule.sniffer=false}rule.sniffer=rule.hasOwnProperty("sniffer")?rule.sniffer:"";rule.sniffer=!!(rule.sniffer&&rule.sniffer!=="0"&&rule.sniffer!=="false");rule.isVideo=rule.hasOwnProperty("isVideo")?rule.isVideo:"";if(rule.sniffer&&!rule.isVideo){rule.isVideo="http((?!http).){12,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)|http((?!http).)*?video/tos*|http((?!http).)*?obj/tos*"}rule.tab_remove=rule.hasOwnProperty("tab_remove")?rule.tab_remove:[];rule.tab_order=rule.hasOwnProperty("tab_order")?rule.tab_order:[];rule.tab_rename=rule.hasOwnProperty("tab_rename")?rule.tab_rename:{};if(rule.headers&&typeof rule.headers==="object"){try{let header_keys=Object.keys(rule.headers);for(let k of header_keys){if(k.toLowerCase()==="user-agent"){let v=rule.headers[k];console.log(v);if(["MOBILE_UA","PC_UA","UC_UA","IOS_UA","UA"].includes(v)){rule.headers[k]=eval(v)}}else if(k.toLowerCase()==="cookie"){let v=rule.headers[k];if(v&&v.startsWith("http")){console.log(v);try{v=fetch(v);console.log(v);rule.headers[k]=v}catch(e){console.log(`从${v}获取cookie发生错误:${e.message}`)}}}}}catch(e){console.log(`处理headers发生错误:${e.message}`)}}else{rule.headers={}}oheaders=deepCopy(rule.headers);rule_fetch_params={headers:rule.headers,timeout:rule.timeout,encoding:rule.encoding};RKEY=typeof key!=="undefined"&&key?key:"drpy_"+(rule.title||rule.host);pre();init_test()}catch(e){console.log(`init_test发生错误:${e.message}`);throw e}}let homeHtmlCache=undefined;function home(filter,home_html,class_parse){console.log("home");home_html=home_html||"";class_parse=class_parse||"";if(typeof rule.filter==="string"&&rule.filter.trim().length>0){try{let filter_json=ungzip(rule.filter.trim());rule.filter=JSON.parse(filter_json)}catch(e){rule.filter={}}}let homeObj={filter:rule.filter||false,MY_URL:rule.homeUrl,class_name:rule.class_name||"",class_url:rule.class_url||"",class_parse:class_parse||rule.class_parse||"",cate_exclude:rule.cate_exclude,home_html:home_html};return homeParse(homeObj)}function homeVod(params){console.log("homeVod");let homeVodObj={"推荐":rule.推荐,double:rule.double,homeUrl:rule.homeUrl,detailUrl:rule.detailUrl};return homeVodParse(homeVodObj)}function category(tid,pg,filter,extend){let cateObj={url:rule.url,"一级":rule.一级,tid:tid,pg:parseInt(pg),filter:filter,extend:extend};return categoryParse(cateObj)}function detail(vod_url){let orId=vod_url;let fyclass="";log("orId:"+orId);if(vod_url.indexOf("$")>-1){let tmp=vod_url.split("$");fyclass=tmp[0];vod_url=tmp[1]}let detailUrl=vod_url.split("@@")[0];let url;if(!detailUrl.startsWith("http")&&!detailUrl.includes("/")){url=rule.detailUrl.replaceAll("fyid",detailUrl).replaceAll("fyclass",fyclass)}else if(detailUrl.includes("/")){url=urljoin(rule.homeUrl,detailUrl)}else{url=detailUrl}let detailObj={orId:orId,url:url,"二级":rule.二级,"二级访问前":rule.二级访问前,detailUrl:detailUrl,fyclass:fyclass,tab_exclude:rule.tab_exclude};return detailParse(detailObj)}function play(flag,id,flags){let playObj={url:id,flag:flag,flags:flags};return playParse(playObj)}function search(wd,quick,pg){if(rule.search_encoding){if(rule.search_encoding.toLowerCase()!=="utf-8"){wd=encodeStr(wd,rule.search_encoding)}}else if(rule.encoding&&rule.encoding.toLowerCase()!=="utf-8"){wd=encodeStr(wd,rule.encoding)}let searchObj={searchUrl:rule.searchUrl,"搜索":rule.搜索,wd:wd,pg:pg||1,quick:quick};return searchParse(searchObj)}function proxy(params){if(rule.proxy_rule&&rule.proxy_rule.trim()){rule.proxy_rule=rule.proxy_rule.trim()}if(rule.proxy_rule.startsWith("js:")){rule.proxy_rule=rule.proxy_rule.replace("js:","")}let proxyObj={params:params,proxy_rule:rule.proxy_rule};return proxyParse(proxyObj)}function sniffer(){let enable_sniffer=rule.sniffer||false;if(enable_sniffer){log("开始执行辅助嗅探代理规则...")}return enable_sniffer}function isVideo(url){let t=0;let is_video;if(rule.isVideo&&rule.isVideo.trim()){is_video=rule.isVideo.trim()}if(is_video.startsWith("js:")){is_video=is_video.replace("js:","");t=1}let isVideoObj={url:url,isVideo:is_video,t:t};let result=isVideoParse(isVideoObj);if(result){log("成功执行辅助嗅探规则并检测到视频地址:\n"+rule.isVideo)}return result}function getRule(key){return key?rule[key]||"":rule}function deepCopy(_obj){return JSON.parse(JSON.stringify(_obj))}function matchesAll(str,pattern,flatten){if(!pattern.global){pattern=new RegExp(pattern.source,"g"+(pattern.ignoreCase?"i":"")+(pattern.multiline?"m":""))}var matches=[];var match;while((match=pattern.exec(str))!==null){matches.push(match)}return flatten?matches.flat():matches}function stringUtils(){Object.defineProperties(String.prototype,{replaceX:{value:function(regex,replacement){let matches=matchesAll(this,regex,true);if(matches&&matches.length>1){const hasCaptureGroup=/\$\d/.test(replacement);if(hasCaptureGroup){return this.replace(regex,m=>m.replace(regex,replacement))}else{return this.replace(regex,(m,p1)=>m.replace(p1,replacement))}}return this.replace(regex,replacement)},configurable:true,enumerable:false,writable:true},parseX:{get:function(){try{return JSON.parse(this)}catch(e){console.log(e.message);return this.startsWith("[")?[]:{}}},configurable:true,enumerable:false}})}function cut(text,start,end,method,All){let result="";let c=(t,s,e)=>{let result="";let rs=[];let results=[];try{let lr=new RegExp(String.raw`${s}`.toString());let rr=new RegExp(String.raw`${e}`.toString());const segments=t.split(lr);if(segments.length<2)return"";let cutSegments=segments.slice(1).map(segment=>{let splitSegment=segment.split(rr);return splitSegment.length<2?undefined:splitSegment[0]+e}).filter(f=>f);if(All){return`[${cutSegments.join(",")}]`}else{return cutSegments[0]}}catch(e){console.log(`Error cutting text:${e.message}`)}return result};result=c(text,start,end);stringUtils();if(method&&typeof method==="function"){result=method(result)}return result}function DRPY(){return{runMain:runMain,getRule:getRule,init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search,proxy:proxy,sniffer:sniffer,isVideo:isVideo,fixAdM3u8Ai:fixAdM3u8Ai}}export default{runMain:runMain,getRule:getRule,init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search,proxy:proxy,sniffer:sniffer,isVideo:isVideo,fixAdM3u8Ai:fixAdM3u8Ai,DRPY:DRPY}; \ No newline at end of file diff --git "a/spider/js/\350\256\276\347\275\256\344\270\255\345\277\203.js" "b/spider/js/\350\256\276\347\275\256\344\270\255\345\277\203.js" index 732fbc0c..0a607edd 100644 --- "a/spider/js/\350\256\276\347\275\256\344\270\255\345\277\203.js" +++ "b/spider/js/\350\256\276\347\275\256\344\270\255\345\277\203.js" @@ -397,7 +397,7 @@ var rule = { d.push(genMultiInput('play_proxy_mode', '设置播放代理模式', '默认为1,可自行配置成其他值如:2 (1 内存加速,2 磁盘加速 其他:内存加速)', images.settings)); d.push(getInput('get_play_proxy_mode', '查看播放代理模式', images.settings)); - d.push(genMultiInput('enable_dr2', '设置drpy2源启用状态', '设置为1启用drpy2脚本服务,需要壳子内置处理;设置为2启用drpy2在线接口服务(默认2,设置其他值关闭)', images.settings)); + d.push(genMultiInput('enable_dr2', '设置drpy2源启用状态', '设置为1启用drpy2脚本服务,需要壳子内置处理;设置为2启用drpy2-fast,需要壳子适配新so(默认1,设置其他值关闭)', images.settings)); d.push(getInput('get_enable_dr2', '查看drpy2源启用状态', images.settings)); d.push(genMultiInput('enable_py', '设置py源启用状态', '设置为1可启用此功能,设置为2启用T4(默认没设置也属于启动,设置其他值关闭)', images.settings)); d.push(getInput('get_enable_py', '查看py源启用状态', images.settings)); From 46e0b73dafe12a34ae0f8ef4cbbf4572c3d10a5a Mon Sep 17 00:00:00 2001 From: Taois Date: Sat, 17 Jan 2026 18:37:13 +0800 Subject: [PATCH 35/99] docs:add link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9e7990da..d911457e 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,7 @@ pm2 restart drpys * [源动力-老](https://sourcepower.top/index) * [电竞专业反应测试](https://www.arealme.com/brain-memory-game/zh/) * [桌面启动器](https://wwbty.lanzouv.com/iDZaP3d3i5ud) +* [不知名获取网盘CK工具](http://sspa8.top:8100/pan/admin/index.php) ## AI接入 From 9beef11c886726ac6a556357b7db09363bb46fa3 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 18:56:48 +0800 Subject: [PATCH 36/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + ...37\350\212\275\347\237\255\345\211\247.js" | 155 ------------ ...33\347\211\233\347\237\255\345\211\247.js" | 229 ------------------ ...\347\225\205\345\220\254[\345\220\254].js" | 92 +------ ...77\351\245\255\347\237\255\345\211\247.js" | 152 ------------ ...\345\260\217\350\257\264[\344\271\246].js" | 159 ++++++------ 6 files changed, 80 insertions(+), 708 deletions(-) delete mode 100644 "spider/js/\346\230\237\350\212\275\347\237\255\345\211\247.js" delete mode 100644 "spider/js/\347\211\233\347\211\233\347\237\255\345\211\247.js" delete mode 100644 "spider/js/\350\245\277\351\245\255\347\237\255\345\211\247.js" diff --git a/.gitignore b/.gitignore index 41e6c6cd..28c6287f 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,4 @@ dist /scripts/test/rsa-test.json /apps/salary/ /jx/_30wmv.js +.DS_Store diff --git "a/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247.js" "b/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247.js" deleted file mode 100644 index f5aed999..00000000 --- "a/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247.js" +++ /dev/null @@ -1,155 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 1, - quickSearch: 1, - title: '星芽短剧', - lang: 'ds' -}) -*/ - -// http://localhost:5757/api/星芽短剧?ac=list&t=1&pg=1 -// http://localhost:5757/api/星芽短剧?ac=detail&ids=https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=3523 -// http://localhost:5757/api/星芽短剧?wd=龙王&pg=1 -// http://localhost:5757/api/星芽短剧?play=http://qcapp.xingya.com.cn/h265/wz_mp40905dingtianhou01.mp4?sign=4db245c4e9cd5bd3d3026e2e0f6147a6&t=674ee966&flag=星芽短剧 -var rule = { - 类型: '影视', - title: '星芽短剧', - desc: '星芽短剧纯js版本', - host: 'https://app.whjzjx.cn', - url: '/cloud/v2/theaterfyfilter', - filter_url: '/home_page?theater_class_id=fyclass&type=1&{{fl.type or "class2_ids=0"}}&page_num=fypage&page_size=24', - searchUrl: '/v3/search', - searchable: 2, - quickSearch: 1, - filterable: 1, - filter: 'H4sIAAAAAAAAA6vmUgACJUMlK4VoMBMEquEssGR2aiVQWqmksiBVSQdVKi8xNxUk93zj7qfzutFlyxJzSlNRTMZuA8I4kFlPW1e8bF6BZhbCTJCS5JzE4mKj+MyUYlsDJQx1tZha8dn3snnv0x1NxNpnQrF9T/uXvFjcSqx9phTb97xvw5Pdi1+saHjWTLSthpRb+6xjxvOl84i10IjycH3Z0PZi0VpiLTSnPFxX7n+xrYvoEKXcwqd9bU/7NxGdUCnPGS+2zni6cj/RUWhGeZAunfe0ZzfRFlKeSF+29z6fMp9YC6ngwSlznq5bQKx9xsbUKGxIzvzGVMgbfS1PdxIdkcaUR+SLCT1P180l1kJLyu1rmfhsC9Glm7ERxRY+2bWJhCg0MaTchzMnPGtEr9JxWmiBxT4UkVguVPFYrloA8HqNcnwIAAA=', - headers: { - 'User-Agent': 'okhttp/4.10.0', - 'Accept-Encoding': 'gzip', - 'x-app-id': '7', - 'platform': '1', - 'manufacturer': 'realme', - 'version_name': '3.3.1', - 'user_agent': 'Mozilla/5.0 (Linux; Android 9; RMX1931 Build/PQ3A.190605.05081124; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36', - 'dev_token': 'BFdbZBGOEgG7QDt01ldOQNNfhO2F-rv4QcugZoFZm5_3DlPJEo_bSBeJ6dW2X3eKzxxKKWz3xJCM_u5PppGMqRuYPxcsVg9a-jriWiIoPZvHMSLbcbxTFuasqgTivTY3GabW1yP57LQSsJNQfKoX1BKYGHducrhb0bTwvigfn3gE*', - 'app_version': '3.1.0.1', - 'device_platform': 'android', - 'personalized_recommend_status': '1', - 'device_type': 'RMX1931', - 'device_brand': 'realme', - 'os_version': '9', - 'channel': 'default', - 'raw_channel': 'default', - 'oaid': '', - 'msa_oaid': '', - 'uuid': 'randomUUID_8a0324bf-03c8-4789-8ef8-12d3bcff28f5', - 'device_id': '24250683a3bdb3f118dff25ba4b1cba1a', - 'ab_id': '', - 'support_h265': '1' - }, - timeout: 5000, - class_name: '剧场&热播剧&会员专享&星选好剧&新剧&阳光剧场', - class_url: '1&2&8&7&3&5', - play_parse: true, - class_parse: async () => { - }, - 预处理: async () => { - let html = await post('https://u.shytkjgs.com/user/v1/account/login', { - headers: { - 'User-Agent': 'okhttp/4.10.0', - 'Accept-Encoding': 'gzip', - 'Content-Type': 'application/x-www-form-urlencoded', - 'x-app-id': '7', - 'platform': '1', - 'manufacturer': 'realme', - 'version_name': '3.3.1', - 'user_agent': 'Mozilla/5.0 (Linux; Android 9; RMX1931 Build/PQ3A.190605.05081124; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36', - 'app_version': '3.3.1', - 'device_platform': 'android', - 'personalized_recommend_status': '1', - 'device_type': 'RMX1931', - 'device_brand': 'realme', - 'os_version': '9', - 'channel': 'default', - 'raw_channel': 'default', - 'oaid': '', - 'msa_oaid': '', - 'uuid': 'randomUUID_914e7a9b-deac-4f80-9247-db56669187df', - 'device_id': '24250683a3bdb3f118dff25ba4b1cba1a', - 'ab_id': '', - 'support_h265': '1' - }, - body: "device=24250683a3bdb3f118dff25ba4b1cba1a&install_first_open=false&first_install_time=1723214205125&last_update_time=1723214205125&report_link_url=" - }); - // log('html:', html); - html = JSON.parse(html); - try { - rule.headers['authorization'] = html.data.token - } catch (e) { - rule.headers['authorization'] = html.data.data.token - } - log('authorization:', rule.headers['authorization']); - }, - 推荐: async () => { - return [] - }, - 一级: async function (tid, pg, filter, extend) { - let {input} = this; - let d = []; - let html = await request(input, {headers: rule.headers}); - let data = JSON.parse(html).data.list; - data.forEach(it => { - let id = 'https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=' + it.theater.id; - d.push({ - url: id, - title: it.theater.title, - img: it.theater.cover_url, - desc: it.theater.theme, - }) - }) - return setResult(d); - }, - 二级: async function (ids) { - let {input} = this; - let urls = []; - let html = await request(input, {headers: rule.headers}); - let data = JSON.parse(html).data; - let vod = { - vod_id: input, - vod_name: data.theaters.son_title, - vod_pic: data.cover_url, - } - let playFroms = []; - let playUrls = []; - data.theaters.forEach(it => { - urls.push(it.num + '$' + encodeURIComponent(it.son_video_url)); - }) - playFroms.push('不知道倾情打造'); - vod.vod_play_from = playFroms.join('$$$'); - playUrls.push(urls.join('#')); - vod.vod_play_url = playUrls.join('$$$'); - return vod - }, - 搜索: async function (wd, quick, pg) { - let {input, KEY} = this - let d = []; - let html = await post(input, {headers: rule.headers, body: {"text": KEY}}) - let list = JSON.parse(html).data.theater.search_data; - list.forEach(it => { - let id = 'https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=' + it.id; - d.push({ - url: id, - title: it.title, - desc: it.total, - img: it.cover_url, - content: it.introduction, - }) - }) - return setResult(d); - }, - lazy: async function (flag, id, flags) { - let {input} = this; - return {parse: 0, url: input, js: ''} - }, -}; diff --git "a/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247.js" "b/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247.js" deleted file mode 100644 index 204129dc..00000000 --- "a/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247.js" +++ /dev/null @@ -1,229 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 1, - quickSearch: 0, - title: '牛牛短句[短]', - '类型': '影视', - lang: 'ds' -}) -*/ - -var rule = { - title: '牛牛短句[短]', - host: 'https://new.tianjinzhitongdaohe.com', - homeUrl: '/api/v1/app/screen/screenType', - searchUrl: '/api/v1/app/search/searchMovie', - url: '/api/v1/app/screen/screenMovie?classify=fyclass&page=fypage', - headers: { - "Cache-Control": "no-cache", - "Content-Type": "application/json;charset=UTF-8", - "User-Agent": "okhttp/4.12.0" - }, - timeout: 5000, - filterable: 1, - limit: 40, - multi: 1, - searchable: 2, - play_parse: true, - search_match: true, - - class_parse: async function () { - const url = `${rule.host}/api/v1/app/screen/screenType`; - try { - const response = await request(url, { - method: 'POST', - headers: rule.headers - }); - const data = JSON.parse(response); - const classes = []; - - if (data.data && data.data[0]?.children?.[0]?.children) { - data.data[0].children[0].children.forEach(vod => { - classes.push({ - type_name: `${vod.name}`, - type_id: vod.name - }); - }); - } - - return { - class: classes, - filters: {} - }; - } catch (e) { - console.error("分类解析错误:", e); - return {class: []}; - } - }, - - 一级: async function () { - const {input, MY_PAGE} = this; - const cid = input.split('classify=')[1].split('&')[0]; - const page = MY_PAGE || 1; - const payload = JSON.stringify({ - condition: { - classify: cid, - typeId: "S1" - }, - pageNum: String(page), - pageSize: rule.limit - }); - - try { - const url = `${rule.host}/api/v1/app/screen/screenMovie`; - const response = await request(url, { - method: 'POST', - headers: rule.headers, - body: payload - }); - const data = JSON.parse(response); - const videos = []; - if (data.data?.records) { - data.data.records.forEach(vod => { - videos.push({ - title: vod.name, - img: vod.cover, - desc: `${vod.totalEpisode}集`, - url: vod.id - }); - }); - } - - return setResult(videos); - } catch (e) { - console.error("一级列表错误:", e); - return []; - } - }, - - 二级: async function () { - const { orId } = this; - let did = orId; - let bofang = ''; - let xianlu = ''; - let content = ''; - - try { - // 获取剧集列表 - const detailPayload = JSON.stringify({ - id: did, - source: 0, - typeId: "S1", - userId: "223664" - }); - - const detailUrl = `${rule.host}/api/v1/app/play/movieDetails`; - const detailResponse = await request(detailUrl, { - method: 'POST', - headers: rule.headers, - body: detailPayload - }); - - const detailData = JSON.parse(detailResponse).data || {}; - if (detailData.episodeList && detailData.episodeList.length > 0) { - const episodes = detailData.episodeList.map(ep => { - return `${ep.episode}$${did}@${ep.id}`; - }); - bofang = episodes.join('#'); - xianlu = '牛牛短句'; - content = detailData.introduce || '暂无剧情介绍'; - } - - return { - vod_name: detailData.name || '未知名称', - vod_pic: detailData.cover || '', - vod_content: content, - vod_play_from: xianlu || '暂无资源', - vod_play_url: bofang || '暂无播放地址$0' - }; - } catch (e) { - console.error("详情解析错误:", e); - return { - vod_name: '加载失败', - vod_pic: '', - vod_content: '详情加载失败,请稍后重试', - vod_play_from: '暂无资源', - vod_play_url: '暂无播放地址$0' - }; - } - }, - - 搜索: async function () { - const {KEY, MY_PAGE} = this; - const page = MY_PAGE || 1; - const payload = JSON.stringify({ - condition: { - typeId: "S1", - value: KEY - }, - pageNum: String(page), - pageSize: rule.limit - }); - - try { - const url = `${rule.host}/api/v1/app/search/searchMovie`; - const response = await request(url, { - method: 'POST', - headers: rule.headers, - body: payload - }); - const data = JSON.parse(response); - const videos = []; - - if (data.data?.records) { - data.data.records.forEach(vod => { - if (rule.search_match && !vod.name.includes(KEY)) return; - - videos.push({ - title: vod.name, - img: vod.cover, - desc: `更新时间${vod.year || '未知'}`, - url: vod.id - }); - }); - } - return setResult(videos); - } catch (e) { - console.error("搜索错误:", e); - return []; - } - }, - - lazy: async function () { - const {input} = this; - const [videoId, episodeId] = input.split('@'); - const payload = JSON.stringify({ - episodeId, - id: videoId, - source: 0, - typeId: "S1", - userId: "223664" - }); - - try { - const url = `${rule.host}/api/v1/app/play/movieDetails`; - const response = await request(url, { - method: 'POST', - headers: rule.headers, - body: payload - }); - const data = JSON.parse(response); - - return { - parse: 0, - url: data.data?.url || '', - header: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36' - } - }; - } catch (e) { - console.error("播放地址获取错误:", e); - return { - parse: 0, - url: '', - header: {} - }; - } - } -}; diff --git "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" index a1f2929f..d55334d0 100644 --- "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" +++ "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" @@ -1,7 +1,7 @@ /* @header({ searchable: 1, - filterable: 0, + filterable: 1, quickSearch: 0, title: '番茄畅听', author: 'EylinSir', @@ -10,92 +10,4 @@ }) */ -var rule = { - 类型: '听书', - author: 'EylinSir', - title: '番茄畅听', - host: 'https://qkfqapi.vv9v.cn', - url: '', - searchUrl: '/api/search?key=**&tab_type=2&offset=((fypage-1)*10)', - detailUrl: '/api/detail?book_id=fyid', - headers: {'User-Agent': 'UC_UA'}, - searchable: 1, - quickSearch: 0, - filterable: 0, - double: true, - play_parse: true, - limit: 12, - - action: async function (action, value) { - if (action === 'only_search') { - return '此源为纯搜索源,你直接全局搜索这个源或者使用此页面的源内搜索就好了'; - } - }, - - 推荐: async function () { - return [{ - vod_id: 'only_search', - vod_name: '纯搜索源哦!', - vod_tag: 'action', - vod_pic: this.publicUrl + '/images/icon_cookie/搜索.jpg' - }]; - }, - - 一级: async function () { - return []; - }, - - 二级: async function () { - let detailApi = `${this.host}/api/detail?book_id=${this.orId}`; - let detailJson = await request(detailApi); - let detailData = JSON.parse(detailJson); - let data = detailData.data.data; - let chaptersApi = `${this.host}/api/book?book_id=${this.orId}`; - let chaptersJson = await request(chaptersApi); - let chaptersData = JSON.parse(chaptersJson); - let bookData = chaptersData.data.data; - let list = bookData.chapterListWithVolume?.flat() || bookData.chapterList || []; - let urls = list.map(it => it.title + '$' + it.itemId + '@' + it.title).join('#'); - return { - vod_id: this.orId, - vod_name: data.book_name, - type_name: data.category, - vod_pic: data.thumb_url || data.expand_thumb_url, - vod_content: data.abstract || data.book_abstract_v2, - vod_remarks: data.sub_info, - vod_director: data.author, - vod_play_from: '番茄畅听', - vod_play_url: urls - }; - }, - - 搜索: async function () { - let {input, MY_PAGE} = this; - let html = await request(input); - let json = JSON.parse(html); - let data = json.data.search_tabs[4].data; - let d = []; - for (let it of data.filter(i => i.book_data)) { - let book = it.book_data[0]; - d.push({ - title: book.book_name, - url: book.book_id, - desc: book.author, - content: book.book_abstract || book.abstract, - pic_url: book.thumb_url - }); - } - return setResult(d); - }, - - lazy: async function () { - let {input} = this; - let parts = input.split('@'); - let itemId = parts[0]; - let toneId = '1'; - let content_url = `${this.host}/api/content?item_id=${itemId}&tab=听书&tone_id=${toneId}`; - let jsonStr = await request(content_url); - let data = JSON.parse(jsonStr); - return {parse: 0, url: data.data.content}; - } -} \ No newline at end of file +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflkKzkuaYnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfnlarojITnlYXlkKwnLAogICAgaG9zdDogJ2h0dHBzOi8vcWtmcWFwaS52djl2LmNuJywKICAgIHVybDogJy9hcGkvZGlzY292ZXI/dGFiPeWQrOS5piZ0eXBlPWZ5Y2xhc3MmZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9e3twYWdlfX0nLAogICAgc2VhcmNoVXJsOiAnL2FwaS9zZWFyY2g/a2V5PSoqJnRhYl90eXBlPTImb2Zmc2V0PSgoZnlwYWdlLTEpKjEwKScsCiAgICBkZXRhaWxVcmw6ICcvYXBpL2RldGFpbD9ib29rX2lkPWZ5aWQnLAogICAgaGVhZGVyczogeydVc2VyLUFnZW50JzogJ1VDX1VBJ30sCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDAsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgZG91YmxlOiB0cnVlLAogICAgcGxheV9wYXJzZTogdHJ1ZSwKICAgIGxpbWl0OiAxMiwKICAgIGNsYXNzX25hbWU6ICfnsr7lk4HlsI/or7Qm55u45aOw6K+E5LmmJuS4lueVjOWOhuWPsiblkI3okZfop6Por7sm5a2m5Lmg5oiQ6ZW/JuaIj+absuiJuuacrybnlJ/mtLvnmb7np5Em5a625bqt5pWZ6IKyJuS6uuaWh+enkeWtpiblhbbku5YnLAogICAgY2xhc3NfdXJsOiAnODk5JjQ0NSYxMiYxMzImNDQ5JjExMyY5NjAmNDUwJjQ0NyYzOScsCiAgICBmaWx0ZXI6IHsKICAgICAgICAiODk5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6Ijg5OSJ9LHsibiI6IumDveW4giIsInYiOiIxIn0seyJuIjoi56m/6LaKIiwidiI6IjM3In0seyJuIjoi546w5Luj6KiA5oOFIiwidiI6IjMifSx7Im4iOiLlj6Tku6PoqIDmg4UiLCJ2IjoiNSJ9LHsibiI6IuaAu+ijgSIsInYiOiIyOSJ9LHsibiI6IueOhOW5uyIsInYiOiI3In0seyJuIjoi6YeN55SfIiwidiI6IjM2In0seyJuIjoi5oKs55aRIiwidiI6IjEwIn0seyJuIjoi54G15byCIiwidiI6IjEwMCJ9LHsibiI6Iuezu+e7nyIsInYiOiIxOSJ9LHsibiI6IuenjeeUsCIsInYiOiIyMyJ9LHsibiI6IueUnOWuoCIsInYiOiI5NiJ9LHsibiI6IuWuoOWmuyIsInYiOiIzMCJ9LHsibiI6IumDveW4gueUn+a0uyIsInYiOiIyIn0seyJuIjoi6LWY5am/IiwidiI6IjI1In0seyJuIjoi5YWI5ama5ZCO54ixIiwidiI6IjI2NSJ9LHsibiI6IuWuq+aWl+WuheaWlyIsInYiOiIyNDYifSx7Im4iOiLpg73luILml6XluLgiLCJ2IjoiMjYxIn0seyJuIjoi5oiY56We6LWY5am/IiwidiI6IjI3In0seyJuIjoi56We5Yy7IiwidiI6IjI2In0seyJuIjoi5b2x6KeG5bCP6K+0IiwidiI6IjQ1In0seyJuIjoi5Zu95YaF5b2x6KeGIiwidiI6Ijk5MSJ9LHsibiI6IuWbveWkluW9seinhiIsInYiOiI5OTIifSx7Im4iOiLnsr7lk4HlsI/or7QiLCJ2IjoiOTcwIn0seyJuIjoi5oKs55aR5o6o55CGIiwidiI6IjE2NSJ9LHsibiI6IuenkeW5u+Wwj+ivtCIsInYiOiIxNjYifSx7Im4iOiLmrabkvqDlsI/or7QiLCJ2IjoiOTkzIn0seyJuIjoi546E5bm75bCP6K+0IiwidiI6Ijk3MSJ9LHsibiI6IueOsOWunuWwj+ivtCIsInYiOiI0MDAifSx7Im4iOiLmg4XmhJ/lsI/or7QiLCJ2IjoiOTcyIn0seyJuIjoi5Lyg57uf546E5bm7IiwidiI6IjI1OCJ9LHsibiI6IueOi+WmgyIsInYiOiI4NSJ9LHsibiI6IuWlh+W5u+S7meS+oCIsInYiOiIyNTkifSx7Im4iOiLokIzlrp0iLCJ2IjoiMjgifSx7Im4iOiLpg73luILohJHmtJ4iLCJ2IjoiMjYyIn0seyJuIjoi6IGM5Zy6IiwidiI6IjEyNyJ9LHsibiI6IuWroeWlsyIsInYiOiI4OCJ9LHsibiI6IumDveW4guS/ruecnyIsInYiOiIxMjQifSx7Im4iOiLlubvmg7PoqIDmg4UiLCJ2IjoiMzIifSx7Im4iOiLnpZ7osaoiLCJ2IjoiMjAifSx7Im4iOiLnqbrpl7QiLCJ2IjoiNDQifSx7Im4iOiLlhbbku5YiLCJ2IjoiMzEifSx7Im4iOiLnjoTlubvoqIDmg4UiLCJ2IjoiMjQ4In0seyJuIjoi546E5bm76ISR5rSeIiwidiI6IjI1NyJ9LHsibiI6IuWOhuWPsuWPpOS7oyIsInYiOiIyNzMifSx7Im4iOiLnp5HlubvmnKvkuJYiLCJ2IjoiOCJ9LHsibiI6IuW5tOS7oyIsInYiOiI3OSJ9LHsibiI6IuWkqeaJjSIsInYiOiI5MCJ9LHsibiI6IuWls+W8uiIsInYiOiI4NiJ9LHsibiI6IuaOqOeQhiIsInYiOiI2MSJ9LHsibiI6IuiFuem7kSIsInYiOiI5MiJ9LHsibiI6IuivuOWkqeS4h+eVjCIsInYiOiI3MSJ9LHsibiI6IuWMu+acryIsInYiOiIyNDcifSx7Im4iOiLmmJ/pmYUiLCJ2IjoiNzcifSx7Im4iOiLpibTlrp0iLCJ2IjoiMTcifSx7Im4iOiLlm6LlrqAiLCJ2IjoiOTQifSx7Im4iOiLmia7njKrlkIPomY4iLCJ2IjoiOTMifSx7Im4iOiLmrabkvqAiLCJ2IjoiMTYifSx7Im4iOiLnjrDoqIDohJHmtJ4iLCJ2IjoiMjY3In0seyJuIjoi6YO95biC56eN55SwIiwidiI6IjI2MyJ9LHsibiI6IuaXoOaVjCIsInYiOiIzODQifSx7Im4iOiLnm5flopMiLCJ2IjoiODEifSx7Im4iOiLpqaznlLIiLCJ2IjoiMjY2In0seyJuIjoi55qH5ZCOIiwidiI6Ijg0In0seyJuIjoi54m556eN5YW1IiwidiI6IjM3NSJ9LHsibiI6IuWkp+WUkCIsInYiOiI3MyJ9LHsibiI6IuWFrOS4uyIsInYiOiI4MyJ9LHsibiI6IuWoseS5kOWciCIsInYiOiI0MyJ9LHsibiI6IumdkuaiheeruemprCIsInYiOiIzODcifSx7Im4iOiLlj6ToqIDohJHmtJ4iLCJ2IjoiMjUzIn0seyJuIjoi5Y6G5Y+y6ISR5rSeIiwidiI6IjI3MiJ9LHsibiI6Iuacq+S4liIsInYiOiI2OCJ9LHsibiI6IuWJkemBkyIsInYiOiI4MCJ9LHsibiI6IueOsOiogOeUnOWuoCIsInYiOiIzOTUifSx7Im4iOiLmuLjmiI/liqjmvKsiLCJ2IjoiNTcifSx7Im4iOiLmtKrojZIiLCJ2IjoiNjYifSx7Im4iOiLlv6vnqb8iLCJ2IjoiMjQifSx7Im4iOiLmmI7mnJ0iLCJ2IjoiMTI2In0seyJuIjoi5aSW5Y2WIiwidiI6Ijc1In0seyJuIjoi5qCh6IqxIiwidiI6IjM4NSJ9LHsibiI6IuWltueIuCIsInYiOiI0MiJ9LHsibiI6IuagoeWbrSIsInYiOiI0In0seyJuIjoi5LiJ5Zu9IiwidiI6IjY3In0seyJuIjoi55u05pKtIiwidiI6IjY5In0seyJuIjoi56m/5LmmIiwidiI6IjM4MiJ9LHsibiI6Iua1t+WymyIsInYiOiI0MCJ9LHsibiI6Iue+jumjnyIsInYiOiI3OCJ9LHsibiI6IuWPjea0viIsInYiOiIzNjkifSx7Im4iOiLnjrDoqIDlpI3ku4ciLCJ2IjoiMjY4In0seyJuIjoi6KW/5ri46KGN55SfIiwidiI6IjM3MyJ9LHsibiI6IuaxgueUnyIsInYiOiIzNzkifSx7Im4iOiLmsJHlm70iLCJ2IjoiMzkwIn0seyJuIjoi5a625bqtIiwidiI6IjEyNSJ9LHsibiI6IuWtpumcuCIsInYiOiI4MiJ9LHsibiI6Iueah+WPlCIsInYiOiI4NyJ9LHsibiI6IuWuoOeJqSIsInYiOiI3NCJ9LHsibiI6IuaXoENQIiwidiI6IjM5MiJ9LHsibiI6IuWls+aJrueUt+ijhSIsInYiOiIzODgifSx7Im4iOiLnvZHmuLgiLCJ2IjoiMzcyIn0seyJuIjoi55eF5aiHIiwidiI6IjM4MCJ9LHsibiI6IueyvueBtSIsInYiOiI4OSJ9LHsibiI6IuiZkOaWhyIsInYiOiI5NSJ9LHsibiI6IumDveW4gumdkuaYpSIsInYiOiIzOTYifSx7Im4iOiLmuIXnqb8iLCJ2IjoiNzYifV19XSwKICAgICAgICAiNDQ1IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0NSJ9LHsibiI6IumDreW+t+e6siIsInYiOiIxMjgifSx7Im4iOiLnlLDov57lhYMiLCJ2IjoiMjAzIn0seyJuIjoi5YiY5YWw6IqzIiwidiI6IjIwMiJ9LHsibiI6IuWwj+WTgSIsInYiOiIxMTQifSx7Im4iOiLoooHpmJTmiJAiLCJ2IjoiMjA0In0seyJuIjoi5Y2V55Sw6IqzIiwidiI6IjIwMSJ9LHsibiI6IuivhOS5piIsInYiOiIxMTAifSx7Im4iOiLnm7jlo7AiLCJ2IjoiMTExIn1dfV0sCiAgICAgICAgIjEyIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjEyIn0seyJuIjoi6a2P5pmL5Y2X5YyX5pydIiwidiI6IjIwOSJ9LHsibiI6IuenpuaxiSIsInYiOiIyMDgifSx7Im4iOiLkuJbnlYzlj7IiLCJ2IjoiMjE0In0seyJuIjoi5ZSQ5a6LIiwidiI6IjIxMCJ9LHsibiI6IuaYjua4hSIsInYiOiIyMTEifSx7Im4iOiLov5HnjrDku6MiLCJ2IjoiMjEzIn0seyJuIjoi5Lit5Zu95Y+yIiwidiI6IjIxMiJ9LHsibiI6IuaImOS6ieWPsiIsInYiOiIyMDYifSx7Im4iOiLlkI3kurrkvKAiLCJ2IjoiMjA3In0seyJuIjoi5Lit5Zu95Y6G5Y+yIiwidiI6IjQwMiJ9LHsibiI6IuS4lueVjOWOhuWPsiIsInYiOiI0MDMifSx7Im4iOiLljoblj7LlsI/or7QiLCJ2IjoiOTg4In0seyJuIjoi5Y6G5Y+y5paH5YyWIiwidiI6IjI0MSJ9XX1dLAogICAgICAgICIxMzIiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiMTMyIn0seyJuIjoi5oiY5LqJIiwidiI6Ijk3In0seyJuIjoi5Lit5Zu95ZCN6JGXIiwidiI6Ijk4In0seyJuIjoi5aSW5Zu95ZCN6JGXIiwidiI6Ijk5In0seyJuIjoi57uP566h5Yqx5b+XIiwidiI6IjI0MiJ9LHsibiI6IuS6uueJqeS8oOiusCIsInYiOiI0MDkifSx7Im4iOiLnu4/lhbjmloflraYiLCJ2IjoiMjQzIn0seyJuIjoi6Z2S5pil5paH5a2mIiwidiI6IjE2OCJ9LHsibiI6IuaImOS6ieWGm+aXhSIsInYiOiI5NzMifV19XSwKICAgICAgICAiNDQ5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0OSJ9LHsibiI6IuazleW+iyIsInYiOiIxNDIifSx7Im4iOiLlv4PnkIYiLCJ2IjoiMTQ2In0seyJuIjoi5b+D55CG5a2mIiwidiI6IjQwNyJ9LHsibiI6IuWwkeWEv+W/g+eQhiIsInYiOiI5ODYifSx7Im4iOiLlv4PnkIbnlpfmhIgiLCJ2IjoiOTk0In0seyJuIjoi5oqV6LWE55CG6LSiIiwidiI6IjE0MyJ9LHsibiI6IuiBjOS4muiBjOWcuiIsInYiOiIxNDUifSx7Im4iOiLnu4/nrqHllYbkuJoiLCJ2IjoiMjM4In0seyJuIjoi5rKf6YCa6KGo6L6+IiwidiI6IjE0NCJ9LHsibiI6IuWKseW/l+aIkOWKnyIsInYiOiIyMzkifV19XSwKICAgICAgICAiMTEzIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjExMyJ9LHsibiI6IuS6rOWJpyIsInYiOiIxNzEifSx7Im4iOiLotorliaciLCJ2IjoiMTcyIn0seyJuIjoi6buE5qKF5oiPIiwidiI6IjE3MyJ9LHsibiI6IuivhOWJpyIsInYiOiIxNzQifSx7Im4iOiLosavliaciLCJ2IjoiMTc1In0seyJuIjoi5piG5puyIiwidiI6IjE3NiJ9LHsibiI6IuiJuuacryIsInYiOiIxMzQifSx7Im4iOiLoibrmnK/mlofljJYiLCJ2IjoiOTQ1In0seyJuIjoi6Z+z5LmQ6Iie6LmIIiwidiI6Ijk0NiJ9LHsibiI6Iue7mOeUuyIsInYiOiI5NTkifSx7Im4iOiLmkYTlvbEiLCJ2IjoiOTYxIn0seyJuIjoi6Ym06LWP55CG6K66IiwidiI6Ijk2MiJ9XX1dLAogICAgICAgICI5NjAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiOTYwIn0seyJuIjoi576O6aOf54O56aWqIiwidiI6IjI0MCJ9LHsibiI6IuaXhea4uCIsInYiOiIxNTgifSx7Im4iOiLlgaXlurflhbvnlJ8iLCJ2IjoiMTU5In0seyJuIjoi6L+Q5Yqo5YGl6LqrIiwidiI6IjQxNyJ9LHsibiI6IuaXtuWwmue+juWmhiIsInYiOiI0MTgifSx7Im4iOiLnvo7po5/kvJHpl7IiLCJ2IjoiNDE5In0seyJuIjoi5a625bGF5peF5ri4IiwidiI6IjQyMCJ9LHsibiI6IumjjuawtOWNoOWNnCIsInYiOiI0MjEifSx7Im4iOiLnmb7np5HluLjor4YiLCJ2IjoiOTYzIn0seyJuIjoi55Sf5rS75oOF5oSfIiwidiI6Ijk2NCJ9XX1dLAogICAgICAgICI0NTAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiNDUwIn0seyJuIjoi5Lqy5a2QIiwidiI6IjQ0NyJ9LHsibiI6IuWpmuWnuyIsInYiOiIyMzQifSx7Im4iOiLnvo7mlociLCJ2IjoiMjMwIn0seyJuIjoi5aSc6K+dIiwidiI6IjIzMiJ9LHsibiI6IuWls+aApyIsInYiOiIyMzEifSx7Im4iOiLlv4PnkIblgaXlurciLCJ2IjoiMjMzIn0seyJuIjoi5oOF5oSf5pWF5LqLIiwidiI6IjIyOSJ9LHsibiI6IuS6p+WQjuaKpOeQhiIsInYiOiIyMjYifSx7Im4iOiLlhL/nq6Xoi7Hor60iLCJ2IjoiMjIyIn0seyJuIjoi5a2V5pyf5L+d5YGlIiwidiI6IjIyNyJ9LHsibiI6IuS6suWtkOWBpeW6tyIsInYiOiIyMjgifSx7Im4iOiLnp5Hmma4iLCJ2IjoiMjIzIn0seyJuIjoi5Zu95a2m5Y6G5Y+yIiwidiI6IjIyNCJ9LHsibiI6IuiDjuaVmeaXqeaVmSIsInYiOiIyMjUifSx7Im4iOiLlhL/nq6XmloflraYiLCJ2IjoiMjIwIn1dfV0sCiAgICAgICAgIjQ0NyI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuWFqOmDqCIsInYiOiI0NDcifSx7Im4iOiLnp5HlrabmioDmnK8iLCJ2IjoiMTAwMCJ9LHsibiI6IuiHqueEtuenkeWtpiIsInYiOiIxMzYifSx7Im4iOiLkvZvlraYiLCJ2IjoiMTE1In0seyJuIjoi56S+56eRIiwidiI6IjIzNyJ9LHsibiI6IuWbveWtpiIsInYiOiIxMTYifSx7Im4iOiLmlaPmlofmiI/liaciLCJ2IjoiMjM2In0seyJuIjoi5paH5YyWIiwidiI6IjExOCJ9LHsibiI6IuaKgOacryIsInYiOiI5NjkifSx7Im4iOiLnp5HlraYiLCJ2IjoiOTc5In0seyJuIjoi5bel5LiaIiwidiI6Ijk4MCJ9LHsibiI6IuWGnOael+eJp+a4lCIsInYiOiI5ODEifSx7Im4iOiLorqHnrpfmnLoiLCJ2IjoiOTgyIn0seyJuIjoi5bu6562R5Zut5p6XIiwidiI6Ijk4MyJ9XX1dLAogICAgICAgICIzOSI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuS6jOasoeWFgyIsInYiOiIzOSJ9LHsibiI6IuWoseS5kCIsInYiOiIxMjEifSx7Im4iOiLnuqrlvZUiLCJ2IjoiMTMzIn0seyJuIjoi5paw6Ze7IiwidiI6IjQ0NiJ9XX1dCiAgICB9LAoKICAgIOS4gOe6pzogYXN5bmMgZnVuY3Rpb24gKHRpZCwgcGcsIGZpbHRlciwgZXh0ZW5kKSB7CiAgICAgICAgbGV0IHBhZ2UgPSBwZyB8fCAxOwogICAgICAgIGxldCB0eXBlSWQgPSAoZXh0ZW5kICYmIGV4dGVuZC50eXBlKSA/IGV4dGVuZC50eXBlIDogdGlkOwogICAgICAgIGxldCBmaW5hbFVybCA9IGAke3RoaXMuaG9zdH0vYXBpL2Rpc2NvdmVyP3RhYj3lkKzkuaYmdHlwZT0ke3R5cGVJZH0mZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9JHtwYWdlfWA7CiAgICAgICAgbGV0IGpzb24gPSBhd2FpdCByZXF1ZXN0KGZpbmFsVXJsKTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoanNvbik7CiAgICAgICAgbGV0IGJvb2tfbGlzdCA9IGRhdGEuY29kZSA9PT0gMjAwID8gZGF0YS5kYXRhIDogW107CiAgICAgICAgbGV0IGQgPSBbXTsKICAgICAgICBib29rX2xpc3QuZm9yRWFjaCgoaXQpID0+IHsKICAgICAgICAgICAgZC5wdXNoKHsKICAgICAgICAgICAgICAgIHRpdGxlOiBpdC5ib29rX25hbWUgfHwgaXQuQm9va05hbWUsCiAgICAgICAgICAgICAgICB1cmw6IGl0LmJvb2tfaWQgfHwgaXQuQm9va0lkLAogICAgICAgICAgICAgICAgZGVzYzogaXQuYXV0aG9yIHx8IGl0LkF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGl0LmFic3RyYWN0IHx8IGl0LkFic3RyYWN0IHx8IGl0LmJvb2tfYWJzdHJhY3RfdjIsCiAgICAgICAgICAgICAgICBwaWNfdXJsOiBpdC50aHVtYl91cmwgfHwgaXQuVGh1bWJVUkwgfHwgaXQuYXVkaW9fdGh1bWJfdXJpCiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KGQpOwogICAgfSwKCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgZGV0YWlsQXBpID0gYCR7dGhpcy5ob3N0fS9hcGkvZGV0YWlsP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgZGV0YWlsSnNvbiA9IGF3YWl0IHJlcXVlc3QoZGV0YWlsQXBpKTsKICAgICAgICBsZXQgZGV0YWlsRGF0YSA9IEpTT04ucGFyc2UoZGV0YWlsSnNvbik7CiAgICAgICAgbGV0IGRhdGEgPSBkZXRhaWxEYXRhLmRhdGEuZGF0YTsKICAgICAgICBsZXQgY2hhcHRlcnNBcGkgPSBgJHt0aGlzLmhvc3R9L2FwaS9ib29rP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgY2hhcHRlcnNKc29uID0gYXdhaXQgcmVxdWVzdChjaGFwdGVyc0FwaSk7CiAgICAgICAgbGV0IGNoYXB0ZXJzRGF0YSA9IEpTT04ucGFyc2UoY2hhcHRlcnNKc29uKTsKICAgICAgICBsZXQgYm9va0RhdGEgPSBjaGFwdGVyc0RhdGEuZGF0YS5kYXRhOwogICAgICAgIGxldCBsaXN0ID0gYm9va0RhdGEuY2hhcHRlckxpc3RXaXRoVm9sdW1lPy5mbGF0KCkgfHwgYm9va0RhdGEuY2hhcHRlckxpc3QgfHwgW107CiAgICAgICAgbGV0IHVybHMgPSBsaXN0Lm1hcChpdCA9PiBpdC50aXRsZSArICckJyArIGl0Lml0ZW1JZCArICdAJyArIGl0LnRpdGxlKS5qb2luKCcjJyk7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdm9kX2lkOiB0aGlzLm9ySWQsCiAgICAgICAgICAgIHZvZF9uYW1lOiBkYXRhLmJvb2tfbmFtZSwKICAgICAgICAgICAgdHlwZV9uYW1lOiBkYXRhLmNhdGVnb3J5LAogICAgICAgICAgICB2b2RfcGljOiBkYXRhLnRodW1iX3VybCB8fCBkYXRhLmV4cGFuZF90aHVtYl91cmwsCiAgICAgICAgICAgIHZvZF9jb250ZW50OiBkYXRhLmFic3RyYWN0IHx8IGRhdGEuYm9va19hYnN0cmFjdF92MiwKICAgICAgICAgICAgdm9kX3JlbWFya3M6IGRhdGEuc3ViX2luZm8sCiAgICAgICAgICAgIHZvZF9kaXJlY3RvcjogZGF0YS5hdXRob3IsCiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfnlarojITnlYXlkKwnLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHVybHMKICAgICAgICB9OwogICAgfSwKCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IGh0bWwgPSBhd2FpdCByZXF1ZXN0KGlucHV0KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgbGV0IGRhdGEgPSBqc29uLmRhdGEuc2VhcmNoX3RhYnNbNF0uZGF0YTsKICAgICAgICBsZXQgZCA9IFtdOwogICAgICAgIGZvciAobGV0IGl0IG9mIGRhdGEuZmlsdGVyKGkgPT4gaS5ib29rX2RhdGEpKSB7CiAgICAgICAgICAgIGxldCBib29rID0gaXQuYm9va19kYXRhWzBdOwogICAgICAgICAgICBkLnB1c2goewogICAgICAgICAgICAgICAgdGl0bGU6IGJvb2suYm9va19uYW1lLAogICAgICAgICAgICAgICAgdXJsOiBib29rLmJvb2tfaWQsCiAgICAgICAgICAgICAgICBkZXNjOiBib29rLmF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGJvb2suYm9va19hYnN0cmFjdCB8fCBib29rLmFic3RyYWN0LAogICAgICAgICAgICAgICAgcGljX3VybDogYm9vay50aHVtYl91cmwKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXRSZXN1bHQoZCk7CiAgICB9LAoKICAgIGxhenk6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IHBhcnRzID0gaW5wdXQuc3BsaXQoJ0AnKTsKICAgICAgICBsZXQgaXRlbUlkID0gcGFydHNbMF07CiAgICAgICAgbGV0IHRvbmVJZCA9ICcxJzsKICAgICAgICBsZXQgY29udGVudF91cmwgPSBgJHt0aGlzLmhvc3R9L2FwaS9jb250ZW50P2l0ZW1faWQ9JHtpdGVtSWR9JnRhYj3lkKzkuaYmdG9uZV9pZD0ke3RvbmVJZH1gOwogICAgICAgIGxldCBqc29uU3RyID0gYXdhaXQgcmVxdWVzdChjb250ZW50X3VybCk7CiAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGpzb25TdHIpOwogICAgICAgIHJldHVybiB7cGFyc2U6IDAsIHVybDogZGF0YS5kYXRhLmNvbnRlbnR9OwogICAgfQp9Ow== \ No newline at end of file diff --git "a/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247.js" "b/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247.js" deleted file mode 100644 index 3a1c8a7b..00000000 --- "a/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247.js" +++ /dev/null @@ -1,152 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 1, - quickSearch: 0, - title: '西饭短剧[短]', - '类型': '影视', - lang: 'ds' -}) -*/ - -var rule = { - title: '西饭短剧[短]', - host: 'https://xifan-api-cn.youlishipin.com', - homeUrl: '/xifan/drama/portalPage?reqType=duanjuCategory&version=2001001&androidVersionCode=28', - searchUrl: '**', - url: '/xifan/drama/portalPage?reqType=aggregationPage&offset=fypage&categoryId=fyclass', - headers: { - 'User-Agent': 'okhttp/3.12.11', - }, - timeout: 5000, - filterable: 1, - limit: 30, - multi: 1, - searchable: 2, - play_parse: true, - search_match: true, - - class_parse: async function () { - let {input} = this; - let html = await request(input); - let classes = []; - let filters = {}; - let data = JSON.parse(html).result.elements[0].contents; - data.forEach((it) => { - const categoryItemVo = it.categoryItemVo || {}; - const typeName = categoryItemVo.oppoCategory; - const typeId = categoryItemVo.categoryId; - const subCategories = categoryItemVo.subCategories || []; - - // 只提取 type 为 duanjuCategory 的作为主分类 - if (it.type && it.type.includes("duanjuCategory")) { - classes.push({ - type_name: typeName, - type_id: `${typeId}@${typeName}`, - }); - } - - // 其他作为筛选条件 - if (subCategories.length > 0) { - filters[typeName] = { - key: categoryItemVo.categoryId, - name: categoryItemVo.oppoCategory, - value: subCategories.map(sub => ({ - n: sub.oppoCategory, - v: `${sub.oppoCategory}@${sub.categoryId}` - })) - }; - } - }); - // 设置筛选条件 - return { - class: classes, - filters: filters - }; - }, - - 一级: async function () { - let {input,MY_PAGE} = this; - const typeId = input.split('categoryId=')[1].split('@')[0]; - const typeName = input.split('categoryId=')[1].split('@')[1]; - let page = (MY_PAGE - 1) * rule.limit; - let current_timestamp = Math.floor(Date.now() / 1000); - let url = `${rule.host}/xifan/drama/portalPage?reqType=aggregationPage&offset=${page}&categoryId=${typeId}&quickEngineVersion=-1&scene=&categoryNames=${encodeURIComponent(typeName)}&categoryVersion=1&density=1.5&pageID=page_theater&version=2001001&androidVersionCode=28&requestId=${current_timestamp}aa498144140ef297&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY1ODI5NCIsInVuIjoiT1BHXzFlZGQ5OTZhNjQ3ZTQ1MjU4Nzc1MTE2YzFkNzViN2QwIiwiZnQiOiIxNzQwNjU4Mjk0In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjMzOTY4MTI2MTQ4NjQxNTM2LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjU4Mjk0LCJ1bm0iOiJPUEdfMWVkZDk5NmE2NDdlNDUyNTg3NzUxMTZjMWQ3NWI3ZDAiLCJpZCI6IjNiMzViZmYzYWE0OTgxNDQxNDBlZjI5N2JkMDY5NGNhIiwiZXhwIjoxNzQxMjYzMDk0LCJkYyI6Imd6cXkifQ.JS3QY6ER0P2cQSxAE_OGKSMIWNAMsYUZ3mJTnEpf-Rc`; - - let d = []; - let html = await request(url, { headers: rule.headers }); - let data = JSON.parse(html).result.elements; - data.forEach((soup) => { - soup.contents.forEach((vod) => { - let dj = vod.duanjuVo; - d.push({ - title: dj.title, - img: dj.coverImageUrl, - desc: dj.total + '集', - url: `${dj.duanjuId}#${dj.source}` - }); - }); - }); - - return setResult(d); - }, - - 二级: async function () { - let {orId} = this; - let [duanjuId, source] = orId.split("#"); - let url = `${rule.host}/xifan/drama/getDuanjuInfo?duanjuId=${duanjuId}&source=${source}&openFrom=homescreen&type=&pageID=page_inner_flow&density=1.5&version=2001001&androidVersionCode=28&requestId=1740658944980aa498144140ef297&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY1ODI5NCIsInVuIjoiT1BHXzFlZGQ5OTZhNjQ3ZTQ1MjU4Nzc1MTE2YzFkNzViN2QwIiwiZnQiOiIxNzQwNjU4Mjk0In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjMzOTY4MTI2MTQ4NjQxNTM2LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjU4Mjk0LCJ1bm0iOiJPUEdfMWVkZDk5NmE2NDdlNDUyNTg3NzUxMTZjMWQ3NWI3ZDAiLCJpZCI6IjNiMzViZmYzYWE0OTgxNDQxNDBlZjI5N2JkMDY5NGNhIiwiZXhwIjoxNzQxMjYzMDk0LCJkYyI6Imd6cXkifQ.JS3QY6ER0P2cQSxAE_OGKSMIWNAMsYUZ3mJTnEpf-Rc`; - - let response = await request(url, { headers: rule.headers }); - let data = JSON.parse(response).result; - VOD = { - vod_name: data.title, - vod_pic: data.coverImageUrl, - vod_content: data.desc || '未知', - vod_remarks: data.updateStatus === 'over' ? `${data.total}集 已完结` : `更新${data.total}集` - }; - - let playUrls = []; - data.episodeList.forEach((ep) => { - playUrls.push(`${ep.index}$${ep.playUrl}`); - }); - - VOD.vod_play_from = '西饭短剧'; - VOD.vod_play_url = playUrls.join("#"); - return VOD; - }, - - 搜索: async function () { - let {input,MY_PAGE,KEY} = this; - let d = []; - let current_timestamp = Math.floor(Date.now() / 1000); - let url = `${rule.host}/xifan/search/getSearchList?keyword=${KEY}84&pageIndex=${MY_PAGE}&version=2001001&androidVersionCode=28&requestId=${current_timestamp}ea3a14bc0317d76f&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY2ODk4NiIsInVuIjoiT1BHX2U5ODQ4NTgzZmM4ZjQzZTJhZjc5ZTcxNjRmZTE5Y2JjIiwiZnQiOiIxNzQwNjY4OTg2In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjM0MDU3ODE4OTgxNDk5OTA0LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjY4OTg2LCJ1bm0iOiJPUEdfZTk4NDg1ODNmYzhmNDNlMmFmNzllNzE2NGZlMTljYmMiLCJpZCI6ImVhZGE1NmEyZWEzYTE0YmMwMzE3ZDc2ZmVjODJjNzc3IiwiZXhwIjoxNzQxMjczNzg2LCJkYyI6ImJqaHQifQ.IwuI0gK077RF4G10JRxgxx4GCG502vR8Z0W9EV4kd-c`; - - let html = await request(url, {headers: rule.headers }); - let data = JSON.parse(html).result.elements; - data.forEach((soup) => { - soup.contents.forEach((vod) => { - let dj = vod.duanjuVo; - let name = dj.title.replace(/<\/?tag>/g, ""); - if (rule.search_match && !new RegExp(KEY, "i").test(name)) { - return; - } - - d.push({ - title: name, - img: dj.coverImageUrl, - desc: dj.total + '集', - url: `${dj.duanjuId}#${dj.source}` - }); - }); - }); - - return setResult(d); - }, - lazy: async function () { - let {input} = this; - return { - parse: 0, - url: input - }; - }, -} diff --git "a/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" index 99a113b4..824f2580 100644 --- "a/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\351\241\266\347\202\271\345\260\217\350\257\264[\344\271\246].js" @@ -10,85 +10,80 @@ */ var rule = { - 类型: '小说',//影视|听书|漫画|小说 - title: '顶点小说[书]', - host: 'https://www.23ddw.cc/', - // 编码: 'gb18030', - 编码: 'utf-8', - url: '/class/fyclass_fypage/', - - // searchUrl: '/modules/article/search.php?searchkey=**&page=fypage', - searchUrl: '/searchss/?searchkey=**&page=fypage', - searchable: 2, - quickSearch: 0, - filterable: 1, - filter: '', - filter_url: '', - filter_def: {}, - headers: { - 'User-Agent': 'PC_UA', - }, - timeout: 5000, - hikerListCol: "text_1", - hikerClassListCol: "text_1", - class_name: '全本', - class_url: '0', - class_parse: '.nav&&ul&&li;a&&Text;a&&href;class/(.*?)_', - cate_exclude: '', - play_parse: true, - lazy: $js.toString(async () => { - log('input:', input); - let html = await request(input); - let title = pdfh(html, '.bookname&&Text'); - let content = pdfh(html, '#content&&Html').replace(/\n/g, "").split("
    ").filter(v => v).slice(0).join("\n").replace(/ /g, ' '); - let ret = JSON.stringify({ - title, - content - }); - input = {parse: 0, url: 'novel://' + ret, js: ''}; - return input; - }), - double: false, - 推荐: '#newscontent&&ul&&li;.s2&&Text;;.s5&&Text;a&&href', - 一级: $js.toString(async () => { - let d = []; - if (MY_CATE == '0') { - input = urljoin(rule.host, '/quanben/' + MY_PAGE); - let html = await request(input); - let lis = pdfa(html, 'table.grid&&tr:gt(0)'); - lis.forEach(it => { - d.push({ - title: pdfh(it, 'a&&Text'), - desc: pdfh(it, 'a:eq(1)&&Text'), - img: "", - url: pd(it, 'a&&href', MY_URL), - }); - }); - } else { - let html = await request(input.split('#')[0]); - let lis = pdfa(html, '#newscontent&&ul&&li'); - lis.forEach(it => { - d.push({ - title: pdfh(it, '.s2&&Text'), - desc: pdfh(it, '.s5&&Text'), - img: "", - url: pd(it, 'a&&href', MY_URL), - }); - }); - } - return setResult(d); - }), - 二级: { - title: 'h1&&Text', - img: '#fmimg&&img&&src', - desc: '#info&&p:eq(-1)&&Text', - content: '#intro&&p&&Text', - tabs: '#list&&dt', - lists: '#list&&a', - tab_text: 'dd&&Text', - list_text: 'body&&Text', - list_url: 'a&&href', - list_url_prefix: '', - }, - 搜索: '#hotcontent&&.item;a&&title;img&&data-original;.blue.visible-xs&&Text;a&&href;dd&&Text', -} \ No newline at end of file + 类型: '小说', + title: '顶点小说[书]', + host: 'https://www.23ddw.cc/', + 编码: 'utf-8', + url: '/class/fyclass_fypage/', + searchUrl: '/searchss/?searchkey=**&page=fypage', + searchable: 2, + quickSearch: 0, + filterable: 1, + filter: '', + filter_url: '', + filter_def: {}, + headers: { 'User-Agent': 'PC_UA' }, + timeout: 5000, + hikerListCol: "text_1", + hikerClassListCol: "text_1", + class_name: '全本', + class_url: '0', + class_parse: '.nav&&ul&&li;a&&Text;a&&href;class/(.*?)_', + cate_exclude: '', + play_parse: true, + lazy: $js.toString(async () => { + log('input:', input); + let html = await request(input); + let title = pdfh(html, '.bookname&&Text'); + let content = pdfh(html, '#content&&Html') || ''; + if (content) { + content = content + .replace(/]*?>.*?<\/script>/gs, '') + .replace(/<\/p>/g, '\n\n') + .replace(//gi, '\n') + .replace(/<[^>]+>/g, '') + .replace(/ /g, ' ') + .replace(/\n\s*\n/g, '\n\n') + .trim(); + } + input = { parse: 0, url: `novel://${JSON.stringify({ title, content })}`, js: '' }; + return input; + }), + double: false, + 一级: $js.toString(async () => { + let d = []; + let url = MY_CATE === '0' + ? urljoin(rule.host, `/quanben/${MY_PAGE}`) + : input.split('#')[0].replace(/_[0-9]+\.html/, '') + `_${MY_PAGE}.html`; + let html = await request(url); + let lis = pdfa(html, '#newscontent ul li') || pdfa(html, '.item'); + lis.forEach(it => { + let title = pdfh(it, 'dt&&Text') || pdfh(it, '.s2&&Text'); + let author = pdfh(it, '.btm a&&Text') || pdfh(it, '.s4&&Text'); + let lastChapter = pdfh(it, '.s3&&Text'); + let img = pdfh(it, 'img&&data-original') + ? pd(it, 'img&&data-original', rule.host) + : (pdfh(it, 'img&&src') ? pd(it, 'img&&src', rule.host) : ''); + d.push({ + title, + desc: `${author} | ${lastChapter}`, + img, + url: pd(it, 'a&&href', rule.host) + }); + }); + return setResult(d); + }), + 二级: { + title: 'h1&&Text', + img: '#fmimg&&img&&data-original;#fmimg&&img&&src', + desc: '#info&&p:eq(-1)&&Text', + content: '#intro&&p&&Text', + tabs: '#list&&dt', + lists: '#list&&a', + tab_text: 'dd&&Text', + list_text: 'body&&Text', + list_url: 'a&&href', + list_url_prefix: '', + }, + 搜索: '#hotcontent&&.item;#newscontent ul li;a&&title;img&&data-original;.btm a&&Text;.blue.visible-xs&&Text;a&&href;dd&&Text;.s2&&Text;.s4&&Text;.s3&&Text' +}; \ No newline at end of file From b6a8616c72d907a66516bac53c9189a32889cb7e Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 18:58:40 +0800 Subject: [PATCH 37/99] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\347\237\255\345\211\247[\347\237\255].js" | 0 ...\347\237\255\345\211\247[\347\237\255].js" | 155 ++++++++++++ ...\347\237\255\345\211\247[\347\237\255].js" | 229 ++++++++++++++++++ ...\347\237\255\345\211\247[\347\237\255].js" | 152 ++++++++++++ ...\347\237\255\345\211\247[\347\237\255].js" | 0 5 files changed, 536 insertions(+) rename "spider/js/\344\270\203\347\214\253\347\237\255\345\211\247.js" => "spider/js/\344\270\203\347\214\253\347\237\255\345\211\247[\347\237\255].js" (100%) create mode 100644 "spider/js/\346\230\237\350\212\275\347\237\255\345\211\247[\347\237\255].js" create mode 100644 "spider/js/\347\211\233\347\211\233\347\237\255\345\211\247[\347\237\255].js" create mode 100644 "spider/js/\350\245\277\351\245\255\347\237\255\345\211\247[\347\237\255].js" rename "spider/js/\350\275\257\351\270\255\347\237\255\345\211\247.js" => "spider/js/\350\275\257\351\270\255\347\237\255\345\211\247[\347\237\255].js" (100%) diff --git "a/spider/js/\344\270\203\347\214\253\347\237\255\345\211\247.js" "b/spider/js/\344\270\203\347\214\253\347\237\255\345\211\247[\347\237\255].js" similarity index 100% rename from "spider/js/\344\270\203\347\214\253\347\237\255\345\211\247.js" rename to "spider/js/\344\270\203\347\214\253\347\237\255\345\211\247[\347\237\255].js" diff --git "a/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247[\347\237\255].js" "b/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247[\347\237\255].js" new file mode 100644 index 00000000..f5aed999 --- /dev/null +++ "b/spider/js/\346\230\237\350\212\275\347\237\255\345\211\247[\347\237\255].js" @@ -0,0 +1,155 @@ +/* +@header({ + searchable: 2, + filterable: 1, + quickSearch: 1, + title: '星芽短剧', + lang: 'ds' +}) +*/ + +// http://localhost:5757/api/星芽短剧?ac=list&t=1&pg=1 +// http://localhost:5757/api/星芽短剧?ac=detail&ids=https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=3523 +// http://localhost:5757/api/星芽短剧?wd=龙王&pg=1 +// http://localhost:5757/api/星芽短剧?play=http://qcapp.xingya.com.cn/h265/wz_mp40905dingtianhou01.mp4?sign=4db245c4e9cd5bd3d3026e2e0f6147a6&t=674ee966&flag=星芽短剧 +var rule = { + 类型: '影视', + title: '星芽短剧', + desc: '星芽短剧纯js版本', + host: 'https://app.whjzjx.cn', + url: '/cloud/v2/theaterfyfilter', + filter_url: '/home_page?theater_class_id=fyclass&type=1&{{fl.type or "class2_ids=0"}}&page_num=fypage&page_size=24', + searchUrl: '/v3/search', + searchable: 2, + quickSearch: 1, + filterable: 1, + filter: 'H4sIAAAAAAAAA6vmUgACJUMlK4VoMBMEquEssGR2aiVQWqmksiBVSQdVKi8xNxUk93zj7qfzutFlyxJzSlNRTMZuA8I4kFlPW1e8bF6BZhbCTJCS5JzE4mKj+MyUYlsDJQx1tZha8dn3snnv0x1NxNpnQrF9T/uXvFjcSqx9phTb97xvw5Pdi1+saHjWTLSthpRb+6xjxvOl84i10IjycH3Z0PZi0VpiLTSnPFxX7n+xrYvoEKXcwqd9bU/7NxGdUCnPGS+2zni6cj/RUWhGeZAunfe0ZzfRFlKeSF+29z6fMp9YC6ngwSlznq5bQKx9xsbUKGxIzvzGVMgbfS1PdxIdkcaUR+SLCT1P180l1kJLyu1rmfhsC9Glm7ERxRY+2bWJhCg0MaTchzMnPGtEr9JxWmiBxT4UkVguVPFYrloA8HqNcnwIAAA=', + headers: { + 'User-Agent': 'okhttp/4.10.0', + 'Accept-Encoding': 'gzip', + 'x-app-id': '7', + 'platform': '1', + 'manufacturer': 'realme', + 'version_name': '3.3.1', + 'user_agent': 'Mozilla/5.0 (Linux; Android 9; RMX1931 Build/PQ3A.190605.05081124; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36', + 'dev_token': 'BFdbZBGOEgG7QDt01ldOQNNfhO2F-rv4QcugZoFZm5_3DlPJEo_bSBeJ6dW2X3eKzxxKKWz3xJCM_u5PppGMqRuYPxcsVg9a-jriWiIoPZvHMSLbcbxTFuasqgTivTY3GabW1yP57LQSsJNQfKoX1BKYGHducrhb0bTwvigfn3gE*', + 'app_version': '3.1.0.1', + 'device_platform': 'android', + 'personalized_recommend_status': '1', + 'device_type': 'RMX1931', + 'device_brand': 'realme', + 'os_version': '9', + 'channel': 'default', + 'raw_channel': 'default', + 'oaid': '', + 'msa_oaid': '', + 'uuid': 'randomUUID_8a0324bf-03c8-4789-8ef8-12d3bcff28f5', + 'device_id': '24250683a3bdb3f118dff25ba4b1cba1a', + 'ab_id': '', + 'support_h265': '1' + }, + timeout: 5000, + class_name: '剧场&热播剧&会员专享&星选好剧&新剧&阳光剧场', + class_url: '1&2&8&7&3&5', + play_parse: true, + class_parse: async () => { + }, + 预处理: async () => { + let html = await post('https://u.shytkjgs.com/user/v1/account/login', { + headers: { + 'User-Agent': 'okhttp/4.10.0', + 'Accept-Encoding': 'gzip', + 'Content-Type': 'application/x-www-form-urlencoded', + 'x-app-id': '7', + 'platform': '1', + 'manufacturer': 'realme', + 'version_name': '3.3.1', + 'user_agent': 'Mozilla/5.0 (Linux; Android 9; RMX1931 Build/PQ3A.190605.05081124; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36', + 'app_version': '3.3.1', + 'device_platform': 'android', + 'personalized_recommend_status': '1', + 'device_type': 'RMX1931', + 'device_brand': 'realme', + 'os_version': '9', + 'channel': 'default', + 'raw_channel': 'default', + 'oaid': '', + 'msa_oaid': '', + 'uuid': 'randomUUID_914e7a9b-deac-4f80-9247-db56669187df', + 'device_id': '24250683a3bdb3f118dff25ba4b1cba1a', + 'ab_id': '', + 'support_h265': '1' + }, + body: "device=24250683a3bdb3f118dff25ba4b1cba1a&install_first_open=false&first_install_time=1723214205125&last_update_time=1723214205125&report_link_url=" + }); + // log('html:', html); + html = JSON.parse(html); + try { + rule.headers['authorization'] = html.data.token + } catch (e) { + rule.headers['authorization'] = html.data.data.token + } + log('authorization:', rule.headers['authorization']); + }, + 推荐: async () => { + return [] + }, + 一级: async function (tid, pg, filter, extend) { + let {input} = this; + let d = []; + let html = await request(input, {headers: rule.headers}); + let data = JSON.parse(html).data.list; + data.forEach(it => { + let id = 'https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=' + it.theater.id; + d.push({ + url: id, + title: it.theater.title, + img: it.theater.cover_url, + desc: it.theater.theme, + }) + }) + return setResult(d); + }, + 二级: async function (ids) { + let {input} = this; + let urls = []; + let html = await request(input, {headers: rule.headers}); + let data = JSON.parse(html).data; + let vod = { + vod_id: input, + vod_name: data.theaters.son_title, + vod_pic: data.cover_url, + } + let playFroms = []; + let playUrls = []; + data.theaters.forEach(it => { + urls.push(it.num + '$' + encodeURIComponent(it.son_video_url)); + }) + playFroms.push('不知道倾情打造'); + vod.vod_play_from = playFroms.join('$$$'); + playUrls.push(urls.join('#')); + vod.vod_play_url = playUrls.join('$$$'); + return vod + }, + 搜索: async function (wd, quick, pg) { + let {input, KEY} = this + let d = []; + let html = await post(input, {headers: rule.headers, body: {"text": KEY}}) + let list = JSON.parse(html).data.theater.search_data; + list.forEach(it => { + let id = 'https://app.whjzjx.cn/v2/theater_parent/detail?theater_parent_id=' + it.id; + d.push({ + url: id, + title: it.title, + desc: it.total, + img: it.cover_url, + content: it.introduction, + }) + }) + return setResult(d); + }, + lazy: async function (flag, id, flags) { + let {input} = this; + return {parse: 0, url: input, js: ''} + }, +}; diff --git "a/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247[\347\237\255].js" "b/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247[\347\237\255].js" new file mode 100644 index 00000000..204129dc --- /dev/null +++ "b/spider/js/\347\211\233\347\211\233\347\237\255\345\211\247[\347\237\255].js" @@ -0,0 +1,229 @@ +/* +@header({ + searchable: 2, + filterable: 1, + quickSearch: 0, + title: '牛牛短句[短]', + '类型': '影视', + lang: 'ds' +}) +*/ + +var rule = { + title: '牛牛短句[短]', + host: 'https://new.tianjinzhitongdaohe.com', + homeUrl: '/api/v1/app/screen/screenType', + searchUrl: '/api/v1/app/search/searchMovie', + url: '/api/v1/app/screen/screenMovie?classify=fyclass&page=fypage', + headers: { + "Cache-Control": "no-cache", + "Content-Type": "application/json;charset=UTF-8", + "User-Agent": "okhttp/4.12.0" + }, + timeout: 5000, + filterable: 1, + limit: 40, + multi: 1, + searchable: 2, + play_parse: true, + search_match: true, + + class_parse: async function () { + const url = `${rule.host}/api/v1/app/screen/screenType`; + try { + const response = await request(url, { + method: 'POST', + headers: rule.headers + }); + const data = JSON.parse(response); + const classes = []; + + if (data.data && data.data[0]?.children?.[0]?.children) { + data.data[0].children[0].children.forEach(vod => { + classes.push({ + type_name: `${vod.name}`, + type_id: vod.name + }); + }); + } + + return { + class: classes, + filters: {} + }; + } catch (e) { + console.error("分类解析错误:", e); + return {class: []}; + } + }, + + 一级: async function () { + const {input, MY_PAGE} = this; + const cid = input.split('classify=')[1].split('&')[0]; + const page = MY_PAGE || 1; + const payload = JSON.stringify({ + condition: { + classify: cid, + typeId: "S1" + }, + pageNum: String(page), + pageSize: rule.limit + }); + + try { + const url = `${rule.host}/api/v1/app/screen/screenMovie`; + const response = await request(url, { + method: 'POST', + headers: rule.headers, + body: payload + }); + const data = JSON.parse(response); + const videos = []; + if (data.data?.records) { + data.data.records.forEach(vod => { + videos.push({ + title: vod.name, + img: vod.cover, + desc: `${vod.totalEpisode}集`, + url: vod.id + }); + }); + } + + return setResult(videos); + } catch (e) { + console.error("一级列表错误:", e); + return []; + } + }, + + 二级: async function () { + const { orId } = this; + let did = orId; + let bofang = ''; + let xianlu = ''; + let content = ''; + + try { + // 获取剧集列表 + const detailPayload = JSON.stringify({ + id: did, + source: 0, + typeId: "S1", + userId: "223664" + }); + + const detailUrl = `${rule.host}/api/v1/app/play/movieDetails`; + const detailResponse = await request(detailUrl, { + method: 'POST', + headers: rule.headers, + body: detailPayload + }); + + const detailData = JSON.parse(detailResponse).data || {}; + if (detailData.episodeList && detailData.episodeList.length > 0) { + const episodes = detailData.episodeList.map(ep => { + return `${ep.episode}$${did}@${ep.id}`; + }); + bofang = episodes.join('#'); + xianlu = '牛牛短句'; + content = detailData.introduce || '暂无剧情介绍'; + } + + return { + vod_name: detailData.name || '未知名称', + vod_pic: detailData.cover || '', + vod_content: content, + vod_play_from: xianlu || '暂无资源', + vod_play_url: bofang || '暂无播放地址$0' + }; + } catch (e) { + console.error("详情解析错误:", e); + return { + vod_name: '加载失败', + vod_pic: '', + vod_content: '详情加载失败,请稍后重试', + vod_play_from: '暂无资源', + vod_play_url: '暂无播放地址$0' + }; + } + }, + + 搜索: async function () { + const {KEY, MY_PAGE} = this; + const page = MY_PAGE || 1; + const payload = JSON.stringify({ + condition: { + typeId: "S1", + value: KEY + }, + pageNum: String(page), + pageSize: rule.limit + }); + + try { + const url = `${rule.host}/api/v1/app/search/searchMovie`; + const response = await request(url, { + method: 'POST', + headers: rule.headers, + body: payload + }); + const data = JSON.parse(response); + const videos = []; + + if (data.data?.records) { + data.data.records.forEach(vod => { + if (rule.search_match && !vod.name.includes(KEY)) return; + + videos.push({ + title: vod.name, + img: vod.cover, + desc: `更新时间${vod.year || '未知'}`, + url: vod.id + }); + }); + } + return setResult(videos); + } catch (e) { + console.error("搜索错误:", e); + return []; + } + }, + + lazy: async function () { + const {input} = this; + const [videoId, episodeId] = input.split('@'); + const payload = JSON.stringify({ + episodeId, + id: videoId, + source: 0, + typeId: "S1", + userId: "223664" + }); + + try { + const url = `${rule.host}/api/v1/app/play/movieDetails`; + const response = await request(url, { + method: 'POST', + headers: rule.headers, + body: payload + }); + const data = JSON.parse(response); + + return { + parse: 0, + url: data.data?.url || '', + header: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36' + } + }; + } catch (e) { + console.error("播放地址获取错误:", e); + return { + parse: 0, + url: '', + header: {} + }; + } + } +}; diff --git "a/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247[\347\237\255].js" "b/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247[\347\237\255].js" new file mode 100644 index 00000000..3a1c8a7b --- /dev/null +++ "b/spider/js/\350\245\277\351\245\255\347\237\255\345\211\247[\347\237\255].js" @@ -0,0 +1,152 @@ +/* +@header({ + searchable: 2, + filterable: 1, + quickSearch: 0, + title: '西饭短剧[短]', + '类型': '影视', + lang: 'ds' +}) +*/ + +var rule = { + title: '西饭短剧[短]', + host: 'https://xifan-api-cn.youlishipin.com', + homeUrl: '/xifan/drama/portalPage?reqType=duanjuCategory&version=2001001&androidVersionCode=28', + searchUrl: '**', + url: '/xifan/drama/portalPage?reqType=aggregationPage&offset=fypage&categoryId=fyclass', + headers: { + 'User-Agent': 'okhttp/3.12.11', + }, + timeout: 5000, + filterable: 1, + limit: 30, + multi: 1, + searchable: 2, + play_parse: true, + search_match: true, + + class_parse: async function () { + let {input} = this; + let html = await request(input); + let classes = []; + let filters = {}; + let data = JSON.parse(html).result.elements[0].contents; + data.forEach((it) => { + const categoryItemVo = it.categoryItemVo || {}; + const typeName = categoryItemVo.oppoCategory; + const typeId = categoryItemVo.categoryId; + const subCategories = categoryItemVo.subCategories || []; + + // 只提取 type 为 duanjuCategory 的作为主分类 + if (it.type && it.type.includes("duanjuCategory")) { + classes.push({ + type_name: typeName, + type_id: `${typeId}@${typeName}`, + }); + } + + // 其他作为筛选条件 + if (subCategories.length > 0) { + filters[typeName] = { + key: categoryItemVo.categoryId, + name: categoryItemVo.oppoCategory, + value: subCategories.map(sub => ({ + n: sub.oppoCategory, + v: `${sub.oppoCategory}@${sub.categoryId}` + })) + }; + } + }); + // 设置筛选条件 + return { + class: classes, + filters: filters + }; + }, + + 一级: async function () { + let {input,MY_PAGE} = this; + const typeId = input.split('categoryId=')[1].split('@')[0]; + const typeName = input.split('categoryId=')[1].split('@')[1]; + let page = (MY_PAGE - 1) * rule.limit; + let current_timestamp = Math.floor(Date.now() / 1000); + let url = `${rule.host}/xifan/drama/portalPage?reqType=aggregationPage&offset=${page}&categoryId=${typeId}&quickEngineVersion=-1&scene=&categoryNames=${encodeURIComponent(typeName)}&categoryVersion=1&density=1.5&pageID=page_theater&version=2001001&androidVersionCode=28&requestId=${current_timestamp}aa498144140ef297&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY1ODI5NCIsInVuIjoiT1BHXzFlZGQ5OTZhNjQ3ZTQ1MjU4Nzc1MTE2YzFkNzViN2QwIiwiZnQiOiIxNzQwNjU4Mjk0In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjMzOTY4MTI2MTQ4NjQxNTM2LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjU4Mjk0LCJ1bm0iOiJPUEdfMWVkZDk5NmE2NDdlNDUyNTg3NzUxMTZjMWQ3NWI3ZDAiLCJpZCI6IjNiMzViZmYzYWE0OTgxNDQxNDBlZjI5N2JkMDY5NGNhIiwiZXhwIjoxNzQxMjYzMDk0LCJkYyI6Imd6cXkifQ.JS3QY6ER0P2cQSxAE_OGKSMIWNAMsYUZ3mJTnEpf-Rc`; + + let d = []; + let html = await request(url, { headers: rule.headers }); + let data = JSON.parse(html).result.elements; + data.forEach((soup) => { + soup.contents.forEach((vod) => { + let dj = vod.duanjuVo; + d.push({ + title: dj.title, + img: dj.coverImageUrl, + desc: dj.total + '集', + url: `${dj.duanjuId}#${dj.source}` + }); + }); + }); + + return setResult(d); + }, + + 二级: async function () { + let {orId} = this; + let [duanjuId, source] = orId.split("#"); + let url = `${rule.host}/xifan/drama/getDuanjuInfo?duanjuId=${duanjuId}&source=${source}&openFrom=homescreen&type=&pageID=page_inner_flow&density=1.5&version=2001001&androidVersionCode=28&requestId=1740658944980aa498144140ef297&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY1ODI5NCIsInVuIjoiT1BHXzFlZGQ5OTZhNjQ3ZTQ1MjU4Nzc1MTE2YzFkNzViN2QwIiwiZnQiOiIxNzQwNjU4Mjk0In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjMzOTY4MTI2MTQ4NjQxNTM2LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjU4Mjk0LCJ1bm0iOiJPUEdfMWVkZDk5NmE2NDdlNDUyNTg3NzUxMTZjMWQ3NWI3ZDAiLCJpZCI6IjNiMzViZmYzYWE0OTgxNDQxNDBlZjI5N2JkMDY5NGNhIiwiZXhwIjoxNzQxMjYzMDk0LCJkYyI6Imd6cXkifQ.JS3QY6ER0P2cQSxAE_OGKSMIWNAMsYUZ3mJTnEpf-Rc`; + + let response = await request(url, { headers: rule.headers }); + let data = JSON.parse(response).result; + VOD = { + vod_name: data.title, + vod_pic: data.coverImageUrl, + vod_content: data.desc || '未知', + vod_remarks: data.updateStatus === 'over' ? `${data.total}集 已完结` : `更新${data.total}集` + }; + + let playUrls = []; + data.episodeList.forEach((ep) => { + playUrls.push(`${ep.index}$${ep.playUrl}`); + }); + + VOD.vod_play_from = '西饭短剧'; + VOD.vod_play_url = playUrls.join("#"); + return VOD; + }, + + 搜索: async function () { + let {input,MY_PAGE,KEY} = this; + let d = []; + let current_timestamp = Math.floor(Date.now() / 1000); + let url = `${rule.host}/xifan/search/getSearchList?keyword=${KEY}84&pageIndex=${MY_PAGE}&version=2001001&androidVersionCode=28&requestId=${current_timestamp}ea3a14bc0317d76f&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY2ODk4NiIsInVuIjoiT1BHX2U5ODQ4NTgzZmM4ZjQzZTJhZjc5ZTcxNjRmZTE5Y2JjIiwiZnQiOiIxNzQwNjY4OTg2In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjM0MDU3ODE4OTgxNDk5OTA0LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjY4OTg2LCJ1bm0iOiJPUEdfZTk4NDg1ODNmYzhmNDNlMmFmNzllNzE2NGZlMTljYmMiLCJpZCI6ImVhZGE1NmEyZWEzYTE0YmMwMzE3ZDc2ZmVjODJjNzc3IiwiZXhwIjoxNzQxMjczNzg2LCJkYyI6ImJqaHQifQ.IwuI0gK077RF4G10JRxgxx4GCG502vR8Z0W9EV4kd-c`; + + let html = await request(url, {headers: rule.headers }); + let data = JSON.parse(html).result.elements; + data.forEach((soup) => { + soup.contents.forEach((vod) => { + let dj = vod.duanjuVo; + let name = dj.title.replace(/<\/?tag>/g, ""); + if (rule.search_match && !new RegExp(KEY, "i").test(name)) { + return; + } + + d.push({ + title: name, + img: dj.coverImageUrl, + desc: dj.total + '集', + url: `${dj.duanjuId}#${dj.source}` + }); + }); + }); + + return setResult(d); + }, + lazy: async function () { + let {input} = this; + return { + parse: 0, + url: input + }; + }, +} diff --git "a/spider/js/\350\275\257\351\270\255\347\237\255\345\211\247.js" "b/spider/js/\350\275\257\351\270\255\347\237\255\345\211\247[\347\237\255].js" similarity index 100% rename from "spider/js/\350\275\257\351\270\255\347\237\255\345\211\247.js" rename to "spider/js/\350\275\257\351\270\255\347\237\255\345\211\247[\347\237\255].js" From 752b4a0c34efe900ba184aa25067398c4fd48833 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Sat, 17 Jan 2026 19:26:52 +0800 Subject: [PATCH 38/99] Update files and clean up spider js scripts --- public/sub/order_common.example.html | 2 + ...57\345\217\257\345\275\261\350\247\206.js" | 60 --------- ...57\350\247\206\345\275\261\351\231\242.js" | 121 ------------------ ...37\350\276\260\345\275\261\351\231\242.js" | 34 ++--- 4 files changed, 16 insertions(+), 201 deletions(-) delete mode 100644 "spider/js/\345\217\257\345\217\257\345\275\261\350\247\206.js" delete mode 100644 "spider/js/\345\217\257\350\247\206\345\275\261\351\231\242.js" rename "spider/js/\345\245\275\344\271\220\345\275\261\350\247\206.js" => "spider/js/\346\230\237\350\276\260\345\275\261\351\231\242.js" (87%) diff --git a/public/sub/order_common.example.html b/public/sub/order_common.example.html index a82a7930..99d5a641 100644 --- a/public/sub/order_common.example.html +++ b/public/sub/order_common.example.html @@ -1,7 +1,9 @@ +豆瓣 设置中心 番茄小说 腾云驾雾 央视大全 +短剧聚合 IPTV [优] [盘] diff --git "a/spider/js/\345\217\257\345\217\257\345\275\261\350\247\206.js" "b/spider/js/\345\217\257\345\217\257\345\275\261\350\247\206.js" deleted file mode 100644 index f1d6224c..00000000 --- "a/spider/js/\345\217\257\345\217\257\345\275\261\350\247\206.js" +++ /dev/null @@ -1,60 +0,0 @@ -/* -@header({ - searchable: 0, - filterable: 0, - quickSearch: 0, - title: '可可影视', - '类型': '影视', - lang: 'ds' -}) -*/ - -var rule = { - 类型: '影视', - title: '可可影视', - host: 'https://www.keke1.app/', - url: '/show/fyclass-----2-fypage.html', - filter_url: '', - searchUrl: '/search?k=**穹&page=fypage', - searchable: 0, - quickSearch: 0, - filterable: 0, - filter: '', - headers: { - 'User-Agent': MOBILE_UA, - }, - timeout: 5000, - class_name: '电影&连续剧&动漫&综艺&短剧', - class_url: '1&2&3&4&6', - play_parse: true, - class_parse: async () => { - }, - 预处理: async () => { - }, - 图片替换: async function (input) { - let {HOST} = this; - // console.log('HOST:', HOST); - return input.replace(HOST, "https://vres.cfaqcgj.com"); - }, - 推荐: '.section-box:eq(2)&&.module-box-inner&&.module-item;*;*;*;*', - double: false, - 一级: '.module-box-inner&&.module-item;.v-item-title:eq(1)&&Text;img:last-of-type&&data-original;.v-item-bottom&&span&&Text;a&&href', - 二级: { - title: '.detail-pic&&img&&alt;.detail-tags&&a&&Text', - img: '.detail-pic&&img&&data-original', - desc: '.detail-info-row-main:eq(-2)&&Text;.detail-tags&&a&&Text;.detail-tags&&a:eq(1)&&Text;.detail-info-row-main:eq(1)&&Text;.detail-info-row-main&&Text', - content: '.detail-desc&&Text', - tabs: '.source-item-label', - //tabs: 'body&&.source-item-label[id]', - lists: '.episode-list:eq(#id) a', - }, - 搜索: '.search-result-list&&a;.title:eq(1)&&Text;*;.search-result-item-header&&Text;a&&href;.desc&&Text', - lazy: $js.toString(async () => { - log('input:', input); - return { - parse: 1, - url: input, - js: 'document.querySelector("#my-video video").click()', - } - }), -}; \ No newline at end of file diff --git "a/spider/js/\345\217\257\350\247\206\345\275\261\351\231\242.js" "b/spider/js/\345\217\257\350\247\206\345\275\261\351\231\242.js" deleted file mode 100644 index 5847df78..00000000 --- "a/spider/js/\345\217\257\350\247\206\345\275\261\351\231\242.js" +++ /dev/null @@ -1,121 +0,0 @@ -/* -@header({ - searchable: 2, - filterable: 1, - quickSearch: 1, - title: '可视影视', - '类型': '影视', - lang: 'ds' -}) -*/ - -var rule = { - 类型:'影视', - title:'可视影视', - desc:'251207_DS', - host:'https://www.ketv.cc', - url: '/s/fyfilter.html', - searchUrl:'/search/**----------fypage---.html', - searchable:2,quickSearch:1,timeout:5000,play_parse:true,filterable:1, - headers: {'User-Agent': 'MOBILE_UA'}, - class_name: '电影&电视剧&综艺&动漫&短剧&动画片', - class_url: 'movie&series&variety&anime&skit&animation', - filter_url: '{{fl.cateId or "fyclass"}}-{{fl.area}}-{{fl.by}}-{{fl.class}}-{{fl.lang}}-{{fl.letter}}---fypage---{{fl.year}}', - - 预处理: async () => { - return [] - }, - - 推荐: async function (tid, pg, filter, extend) { - return this.一级(tid, pg, filter, extend); - }, - - 一级: async function (tid, pg, filter, extend) { - let {input, pdfa, pdfh, pd} = this; - let html = await request(input); - let d = []; - let data = pdfa(html, '.lazyload'); - data.forEach((it) => { - d.push({ - title: pdfh(it, 'a&&title'), - pic_url: pd(it, '.lazyload&&data-original'), - desc: pdfh(it, '.text_right&&Text'), - url: pd(it, 'a&&href'), - }) - }); - return setResult(d) - }, - - 二级: async function (ids) { - let {input, pdfa, pdfh, pd} = this; - let html = await request(input); - let VOD = {}; - VOD.vod_id = input; - VOD.vod_name = pdfh(html, 'h2.title&&Text'); - VOD.type_name = pdfh(html, '.data:contains(类型)&&Text').replace('类型:', ''); - VOD.vod_pic = pd(html, '#detail_rating img&&src', input); - VOD.vod_remarks = pdfh(html, '.data_style&&Text'); - VOD.vod_content = pdfh(html, '.content_desc span&&Text'); - VOD.vod_year = pdfh(html, '.data:contains(年份) a&&Text'); - VOD.vod_area = pdfh(html, '.data:contains(地区) a&&Text'); - VOD.vod_director = pdfh(html, '.data:contains(导演)&&Text').replace('导演:', '').trim(); - VOD.vod_actor = pdfh(html, '.data:contains(主演)&&Text').replace('主演:', '').trim(); - let r_ktabs = pdfa(html,'#NumTab a'); - let ktabs = r_ktabs.map(it => { - let altText = pd(it, 'a&&alt'); - return altText || pdfh(it, 'Text').replace(/^\s*[\uE000-\uF8FF]+\s*/, '').trim(); - }).filter(name => name && !name.includes('Playlist')); - VOD.vod_play_from = ktabs.join('$$$'); - let klists = []; - let r_plists = pdfa(html, '.play_list_box .content_playlist.clearfix'); - r_plists.forEach((rp, index) => { - if (index < ktabs.length) { - let klist = pdfa(rp, 'a').map((it) => { - return pdfh(it, 'a&&Text') + '$' + pd(it, 'a&&href', input); - }).filter(item => { - return !item.includes('APP播放'); - }); - klist = klist.join('#'); - klists.push(klist); - } - }); - VOD.vod_play_url = klists.join('$$$'); - return VOD; - }, - - 搜索: async function (wd, quick, pg) { - return this.一级(wd, quick, pg); - }, - - lazy: async function lazyFunc() { - let html = await request(input); - let kcode = JSON.parse(html.split('aaaa=')[1].split('<')[0]); - let kurl = kcode.url; - if (/\.(m3u8|mp4)/.test(kurl)) { - input = { - jx: 0, - parse: 0, - url: kurl, - header: { - 'User-Agent': MOBILE_UA, - 'Referer': getHome(kurl) - } - }; - } else { - input = { - jx: 0, - parse: 1, - url: input - }; - } -}, -filter_def:{movie:{cateId:'movie'},series:{cateId:'series'},variety:{cateId:'variety'},anime:{cateId:'anime'},skit:{cateId:'skit'},animation:{cateId:'animation'}}, -filter:{ -"movie":[{"key":"cateId","name":"分类","value":[{"n":"全部","v":"all"},{"n":"动作片","v":"Action"},{"n":"喜剧片","v":"Funny"},{"n":"爱情片","v":"Lovestory"},{"n":"科幻片","v":"Science"},{"n":"恐怖片","v":"terrorist"},{"n":"剧情片","v":"plot"},{"n":"战争片","v":"war"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":""},{"n":"大陆","v":"大陆"},{"n":"香港","v":"香港"},{"n":"台湾","v":"台湾"},{"n":"美国","v":"美国"},{"n":"法国","v":"法国"},{"n":"英国","v":"英国"},{"n":"日本","v":"日本"},{"n":"韩国","v":"韩国"},{"n":"德国","v":"德国"},{"n":"泰国","v":"泰国"},{"n":"印度","v":"印度"},{"n":"意大利","v":"意大利"},{"n":"西班牙","v":"西班牙"},{"n":"加拿大","v":"加拿大"},{"n":"其他","v":"其他"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"},{"n":"0-9","v":"0-9"}]},{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}], -"series":[{"key":"cateId","name":"分类","value":[{"n":"全部","v":"all"},{"n":"国产剧","v":"china"},{"n":"香港剧","v":"hongkong"},{"n":"韩国剧","v":"korea"},{"n":"欧美剧","v":"eus"},{"n":"日本剧","v":"japan"},{"n":"台湾剧","v":"taiwan"},{"n":"海外剧","v":"overseas"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":""},{"n":"大陆","v":"大陆"},{"n":"香港","v":"香港"},{"n":"台湾","v":"台湾"},{"n":"美国","v":"美国"},{"n":"法国","v":"法国"},{"n":"英国","v":"英国"},{"n":"日本","v":"日本"},{"n":"韩国","v":"韩国"},{"n":"德国","v":"德国"},{"n":"泰国","v":"泰国"},{"n":"印度","v":"印度"},{"n":"意大利","v":"意大利"},{"n":"西班牙","v":"西班牙"},{"n":"加拿大","v":"加拿大"},{"n":"其他","v":"其他"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"},{"n":"0-9","v":"0-9"}]},{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}], -"variety":[{"key":"cateId","name":"分类","value":[{"n":"全部","v":"all"},{"n":"大陆","v":"cn"},{"n":"日韩","v":"JapanKorea"},{"n":"港台","v":"HongKongTaiwan"},{"n":"欧美","v":"Eusa"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":""},{"n":"大陆","v":"大陆"},{"n":"香港","v":"香港"},{"n":"台湾","v":"台湾"},{"n":"美国","v":"美国"},{"n":"法国","v":"法国"},{"n":"英国","v":"英国"},{"n":"日本","v":"日本"},{"n":"韩国","v":"韩国"},{"n":"德国","v":"德国"},{"n":"泰国","v":"泰国"},{"n":"印度","v":"印度"},{"n":"意大利","v":"意大利"},{"n":"西班牙","v":"西班牙"},{"n":"加拿大","v":"加拿大"},{"n":"其他","v":"其他"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"},{"n":"0-9","v":"0-9"}]},{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}], -"anime":[{"key":"cateId","name":"分类","value":[{"n":"全部","v":"all"},{"n":"国产","v":"chn"},{"n":"日本","v":"jp"},{"n":"欧美","v":"usa"},{"n":"海外","v":"others"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":""},{"n":"大陆","v":"大陆"},{"n":"香港","v":"香港"},{"n":"台湾","v":"台湾"},{"n":"美国","v":"美国"},{"n":"法国","v":"法国"},{"n":"英国","v":"英国"},{"n":"日本","v":"日本"},{"n":"韩国","v":"韩国"},{"n":"德国","v":"德国"},{"n":"泰国","v":"泰国"},{"n":"印度","v":"印度"},{"n":"意大利","v":"意大利"},{"n":"西班牙","v":"西班牙"},{"n":"加拿大","v":"加拿大"},{"n":"其他","v":"其他"}]},{"key":"year","name":"年份","value":[{"n":"全部","v":""},{"n":"2024","v":"2024"},{"n":"2023","v":"2023"},{"n":"2022","v":"2022"},{"n":"2021","v":"2021"},{"n":"2020","v":"2020"},{"n":"2019","v":"2019"},{"n":"2018","v":"2018"},{"n":"2017","v":"2017"},{"n":"2016","v":"2016"},{"n":"2015","v":"2015"},{"n":"2014","v":"2014"},{"n":"2013","v":"2013"},{"n":"2012","v":"2012"},{"n":"2011","v":"2011"},{"n":"2010","v":"2010"},{"n":"2009","v":"2009"},{"n":"2008","v":"2008"}]},{"key":"letter","name":"字母","value":[{"n":"全部","v":""},{"n":"A","v":"A"},{"n":"B","v":"B"},{"n":"C","v":"C"},{"n":"D","v":"D"},{"n":"E","v":"E"},{"n":"F","v":"F"},{"n":"G","v":"G"},{"n":"H","v":"H"},{"n":"I","v":"I"},{"n":"J","v":"J"},{"n":"K","v":"K"},{"n":"L","v":"L"},{"n":"M","v":"M"},{"n":"N","v":"N"},{"n":"O","v":"O"},{"n":"P","v":"P"},{"n":"Q","v":"Q"},{"n":"R","v":"R"},{"n":"S","v":"S"},{"n":"T","v":"T"},{"n":"U","v":"U"},{"n":"V","v":"V"},{"n":"W","v":"W"},{"n":"X","v":"X"},{"n":"Y","v":"Y"},{"n":"Z","v":"Z"},{"n":"0-9","v":"0-9"}]},{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}], -"skit":[{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}], -"animation":[{"key":"area","name":"地区","value":[{"n":"全部","v":"all"},{"n":"大陆动画片","v":"大陆"},{"n":"日本动画片","v":"日本"},{"n":"美国动画片","v":"美国"},{"n":"韩国动画片","v":"韩国"},{"n":"香港动画片","v":"香港"}]},{"key":"by","name":"排序","value":[{"n":"按最新","v":"time"},{"n":"按最热","v":"hits"},{"n":"按评分","v":"score"}]}] -} -} \ No newline at end of file diff --git "a/spider/js/\345\245\275\344\271\220\345\275\261\350\247\206.js" "b/spider/js/\346\230\237\350\276\260\345\275\261\351\231\242.js" similarity index 87% rename from "spider/js/\345\245\275\344\271\220\345\275\261\350\247\206.js" rename to "spider/js/\346\230\237\350\276\260\345\275\261\351\231\242.js" index 243cc497..a95204f1 100644 --- "a/spider/js/\345\245\275\344\271\220\345\275\261\350\247\206.js" +++ "b/spider/js/\346\230\237\350\276\260\345\275\261\351\231\242.js" @@ -3,17 +3,18 @@ searchable: 1, filterable: 1, quickSearch: 0, - title: '好乐影视', + title: '星辰影院', + '类型': '影视', lang: 'ds' }) */ var rule = { 类型: '影视', - title: '好乐影视', - host: 'https://www.haolev.com', - url: '/haoshow/fyfilter', - searchUrl: '/lesearch/**----------fypage---.html', + title: '星辰影院', + host: 'https://www.xcyycn.com', + url: '/vs/fyfilter', + searchUrl: '/s.html?wd=**&submit=', headers: {'User-Agent': 'MOBILE_UA'}, searchable: 1, quickSearch: 0, filterable: 1, play_parse: true, double: false, limit: 6, filter_url: '{{fl.cateId}}-{{fl.area}}-{{fl.by}}-{{fl.class}}-----fypage---{{fl.year}}.html', @@ -24,22 +25,15 @@ var rule = { class_url: '1&2&4&3', filter: 'H4sIAAAAAAAAA+2Zy04bSRSG9/MYXrOohtwmrzLKwhNZSpRMRoJMJBQhQcDEBgcbROw4OEDENYRLcxkwDbZfxlVtv8WUXVXnnJ4hx42HRRbe+T+nbn91ddXX5bcJL/H4t7eJF6nxxOPE05fJsbHEUOJV8o+UljK7o6bTWr9Jvvwr1S33qhNO77andzthLRITQzY6t9usVWzUCsgVK7otlzPC5cKdRXl5ZXNWuJyaKqjJos1ZAfUyx3ZwKKA/GDgKaDPzqRlkXZtGuFzr0Je1jzZnBfEXLl+hv46ANqfn1LvPrk0jYJxzR2Ftz43TCKj3bj8sLrp6RkB/s0vt8jfXnxGQ23qPc2YF5A7PZXDgckZAbmFW5k9czgiXa16va8c2ZwXUy2+2NmA+jXC59tpp87Jgc1ZAvUJOTcJzNwLmulHQs+jm2giYl4PtZn3dzYsRMJ9rB2H2vZtPI7BerpVZhXpdAf1tNXDVWgHjnGmE37fcOI2A/qbq7c91158RuJbyauUE1lJXQL3KWjMIwp1JVxU0zNyXJfXJ9WrFxJNO1ryNydFUkryMFV/mgrgv4+ZOuzzrDBkB3W6XVfXIdWsEPmhfXdbhQXcFGKovyJWac2METERpS1X23UQYgQvkG9azAh7K/DHmrIA2Tz9izgoYZ/0Cc1ZAvZm8diwz7t1BTZZCmNcLp4yrwWp4GRozYa2kim6aUON2sK7mG7ph2BGchhIffBlsu7QR6M2n3vyIt/S5PJx29YyAekVfdyS/fHVVQYO3/Imsz8tD9xBRQxv1UzMfzQC2LBqCcVTWWpOnegBuKKBhRSyuynTVrQgjoPbFmZ5WV9UIGOOHC5l2W40V0VmT/rWugAP8dxS85Pbk7pRzYQTkygFZBEaQw0P6yzgI1LgdzqlKCbbDroDxL5X1JujGbwR9ccdTyVHy4l6eNa9qMV/cYTF8z8a6P0l8BOMjND6M8WEa9zDu0bjAuCBx71eI658k/gjjj2j8IcYf0vgDjD+g8fsYv0/j6Nejfj3061G/Hvr1qF8P/XrUr4d+PepXoF9B/Qr0K6hfgX4F9SvQr6B+BfoV1K9Av4L6FehXUL8C/QrqV6BfQf0K9Kt/0mX5+zguSrWwJIP8fxalymVV6bxdOrNtvH6uS+PLltUnmPKXbfLZ89djNNk6mpEZd+iMPf1zNNXp/snQL4nhHzNmeHwlV+fjHmsrtWYAO64RMID9HX0oudfdiDhHHnc8ccchd+Spvy/kJnCrEbG2foZbWd5l+JpjTI5NOeZjWZ9hU46T++VW9vuBYX2OTTn+5Lic/V4J9vDbwoo47M3xLsfQLJczvNsvQ9/IyQOa/b/E15tVe5MoS9IcpfakzRiczHDg3ZFob+bnvhh6MzNLurci1t7keWumHZDngDwH5Hkzed67U/LU56u6/h7hTxsiR0fnUKDlIqEorUbL0RCUqx7pgytajoaixBktR0OE3H54i8lRJEem7G0kd4vJUCRHdSwJM2TDESZ7q8gQNEdgHEFzhMmRG3ubzNA1R8IctXLkrQqr4T7MixFxKDKcPmh9hWtRI35iUuyXBjnC7PvekyHF3hzYm9Z602YM0mKIkr23ZQh5wD0D7hlwzy24Z+SuuKe7h4ZX161sENlWbSjKKZFykVCUj6LlaCjKR9FyNASbbM9/2cxVCzncQcOmN3Ms8xvYBuo4JzJ70q1U5QZ86RkRh7ZYwmFOZJZGOBJj6K512Gj5GdemEfg006pahefYFXGoqV8S4+7s2DtJ7r6L++++vtDeWMMjvCN+YlLhaISjmH5Jhf2nkqOYGDdWDAvcwa1UjFu1u7i36u/OacA1A64ZcM0NXDPxDyQRoaiuJgAA', lazy: async function () { - let {input, pdfa, pdfh, pd} = this - const html = JSON.parse((await req(input)).content.match(/r player_.*?=(.*?) Date: Sat, 17 Jan 2026 19:51:14 +0800 Subject: [PATCH 39/99] =?UTF-8?q?Add=20=E7=B1=B3=E5=85=94=E9=9F=B3?= =?UTF-8?q?=E4=B9=90[=E5=90=AC].js=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\351\237\263\344\271\220[\345\220\254].js" | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 "spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" diff --git "a/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" new file mode 100644 index 00000000..6a2a6720 --- /dev/null +++ "b/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" @@ -0,0 +1,59 @@ +/* +@header({ + searchable: 2, + filterable: 0, + quickSearch: 0, + title: '米兔音乐', + '类型': '影视', + lang: 'ds' +}) +*/ + +var rule = { + title: '米兔音乐', + host: 'https://api.qqmp3.vip', + url: '/api/fyclass', + searchUrl: '/api/songs.php?type=search&keyword=**', + class_name: '热门歌曲&新歌曲&随机歌曲', + class_url: 'songs.php&songs.php?type=new&songs.php?type=rand', + searchable: 2, + quickSearch: 0, + filterable: 0, + play_parse: true, + limit: 6, + double: true, + headers: { + 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; V2284A Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36', + 'Accept': '*/*', + 'Origin': 'https://www.qqmp3.vip', + 'referer': 'https://www.qqmp3.vip', + 'x-requested-with': 'com.mmbox.xbrowser', + 'Sec-Fetch-Site': 'same-site', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Dest': 'empty', + 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' + }, + 推荐: '*', + 一级: 'json:data;name;pic;artist;rid', + 二级: '*', + 搜索: 'json:data;name;pic;artist;rid', + lazy: async function() { + let ridMatch = this.input.match(/api\/([^/?]+)/); + if (!ridMatch) return this.input; + let rid = ridMatch[1]; + let api = 'https://api.qqmp3.vip/api/kw.php?rid=' + rid; + // console.log('解析接口:', api); + let json = await request(api); + let data = JSON.parse(json); + if (data.code === 200 && data.data?.url) { + return { + parse: 0, + url: data.data.url, + header: this.headers, + lrc: data.data.lrc || '', + playMode: 'repeat' + }; + } + return this.input; + }, +}; \ No newline at end of file From 36d010af9563a894cd094a830afd4d358d8b4dad Mon Sep 17 00:00:00 2001 From: Taois Date: Sat, 17 Jan 2026 22:54:16 +0800 Subject: [PATCH 40/99] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E5=92=8C=E5=81=9C=E6=AD=A2=E7=9A=84=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 4 +++- public/index.html | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 6b140a7a..2c27bfac 100644 --- a/index.js +++ b/index.js @@ -250,7 +250,7 @@ const start = async () => { } else { console.log('Not running on Vercel!'); } - + return true; } catch (err) { fastify.log.error(err); process.exit(1); @@ -265,8 +265,10 @@ const stop = async () => { // 停止主服务器 await fastify.server.close(); console.log('🛑 所有服务已优雅停止'); + return true; } catch (err) { fastify.log.error(`停止服务器时发生错误:${err.message}`); + return false; } }; diff --git a/public/index.html b/public/index.html index 796ff944..4b19495f 100644 --- a/public/index.html +++ b/public/index.html @@ -161,6 +161,7 @@

    友链(白嫖接口服务)

  • 源动力-老
  • 电竞专业反应测试
  • 桌面启动器
  • +
  • 不知名获取网盘CK工具
  • AI接入

      From 0edd3fe18e027d539555a879136d32b6fa0ac335 Mon Sep 17 00:00:00 2001 From: Taois Date: Sun, 18 Jan 2026 01:52:40 +0800 Subject: [PATCH 41/99] =?UTF-8?q?feat:=20=E7=A1=AE=E4=BF=9D=E5=B0=8F?= =?UTF-8?q?=E8=AF=B4=E6=BA=90=E9=83=BD=E6=9C=89=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\203\347\214\253\345\260\217\350\257\264[\344\271\246].js" | 3 +++ ...5\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" | 3 +++ ...0\203\347\214\253\345\260\217\350\257\264[\344\271\246].py" | 1 + 3 files changed, 7 insertions(+) diff --git "a/spider/js/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].js" index 45a2079e..6bc4e80b 100644 --- "a/spider/js/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].js" @@ -5,11 +5,14 @@ quickSearch: 0, title: '七猫小说[书]', logo: 'https://cdn-front.qimao.com/global/static/images/favicon2022.ico', + author: '道长', + '类型': '小说', lang: 'ds' }) */ var rule = { + author: '道长', 类型: '小说', //影视|听书|漫画|小说 title: '七猫小说[书]', host: 'https://www.qimao.com/', diff --git "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" index 12279717..7a5a2929 100644 --- "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" @@ -4,6 +4,8 @@ filterable: 1, quickSearch: 0, title: '番茄小说[书]', + author: '道长', + '类型': '小说', lang: 'ds' }) */ @@ -29,6 +31,7 @@ const fqweb_host = 'https://qkfqapi.vv9v.cn'; // const fqweb_host = 'http://8.148.83.169:22222/docs'; //备选 var rule = { + author: '道长', 类型: '小说', title: '番茄小说[书]', desc: '番茄小说纯js版本', diff --git "a/spider/py/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].py" "b/spider/py/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].py" index 1b0bde65..3da53506 100644 --- "a/spider/py/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].py" +++ "b/spider/py/\344\270\203\347\214\253\345\260\217\350\257\264[\344\271\246].py" @@ -4,6 +4,7 @@ filterable: 1, quickSearch: 1, title: '七猫小说', + 类型: '小说', logo: 'https://cdn-front.qimao.com/global/static/images/favicon2022.ico', lang: 'hipy' }) From be0d97d2b34f932e6246c0655c014f04b9428f9f Mon Sep 17 00:00:00 2001 From: Taois Date: Sun, 18 Jan 2026 01:59:36 +0800 Subject: [PATCH 42/99] =?UTF-8?q?feat:=20=E5=8F=91=E5=B8=83=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ docs/updateRecord.md | 11 +++++++++++ package.json | 2 +- public/index.html | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d911457e..3cbdcc29 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,10 @@ nodejs作为服务端的drpy实现。全面升级异步写法 ## 更新记录 +### 20260118 + +更新至V1.3.18 + ### 20260115 更新至V1.3.17 diff --git a/docs/updateRecord.md b/docs/updateRecord.md index 8fe8d811..4a487152 100644 --- a/docs/updateRecord.md +++ b/docs/updateRecord.md @@ -1,5 +1,16 @@ # drpyS更新记录 +### 20260118 + +更新至V1.3.18 + +1. 合并E佬修改的源,新增&修复源 +2. 新增drpy2-fast壳依赖,需自行适配爱老so文件,取消不可用的dr2的t4模式,改为使用drpy2-fast本地依赖 +3. 规范一些小说源的代码,确保统一返回了类型:'小说' +4. 修改了index.js中的start、stop函数确保有返回值,适配新版zy本地插件 +5. 调整了部分内置解析 + 其它细节自测... + ### 20260115 更新至V1.3.17 diff --git a/package.json b/package.json index 25b196bc..e350953d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "drpy-node", - "version": "1.3.17", + "version": "1.3.18", "main": "index.js", "type": "module", "scripts": { diff --git a/public/index.html b/public/index.html index 4b19495f..83d6552e 100644 --- a/public/index.html +++ b/public/index.html @@ -67,6 +67,8 @@

      免费壳子推荐

    • 皮卡丘

    更新记录

    +

    20260118

    +

    更新至V1.3.18

    20260115

    更新至V1.3.17

    20260113

    From fe27ceafd6957a63598948cd967a55d6e3b9163a Mon Sep 17 00:00:00 2001 From: Taois Date: Sun, 18 Jan 2026 17:28:42 +0800 Subject: [PATCH 43/99] =?UTF-8?q?feat:=20=E5=B0=9D=E8=AF=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=BA=95=E5=B1=82=E6=8B=A6=E6=88=AA=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=A4=B4=E7=9A=84ua=E6=89=8B=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs_drpy/fetchAxios.js | 58 +++++++++++++++++++++++++- spider/js/_debug.js | 85 +++++++++++++++++++++++++++++++++++++++ spider/js/_lib.request.js | 28 +++++++++++-- utils/createAxiosAgent.js | 21 ++++++++-- 4 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 spider/js/_debug.js diff --git a/libs_drpy/fetchAxios.js b/libs_drpy/fetchAxios.js index 789fe5c2..4e90ffa8 100644 --- a/libs_drpy/fetchAxios.js +++ b/libs_drpy/fetchAxios.js @@ -4,6 +4,50 @@ */ import FormData from 'form-data'; import https from "https"; +import diagnosticsChannel from 'diagnostics_channel'; + +let undiciStripUASubscribed = false; + +function ensureUndiciStripUASubscription() { + if (undiciStripUASubscribed) { + return; + } + undiciStripUASubscribed = true; + + diagnosticsChannel.channel('undici:request:create').subscribe(({request}) => { + if (!request || !Array.isArray(request.headers)) { + return; + } + const headers = request.headers; + + let shouldStrip = false; + for (let i = 0; i < headers.length; i += 2) { + const k = headers[i]; + if (typeof k === 'string' && k.toLowerCase() === 'x-remove-user-agent') { + shouldStrip = true; + break; + } + } + if (!shouldStrip) { + return; + } + + for (let i = 0; i < headers.length; i += 2) { + const k = headers[i]; + if (typeof k === 'string' && k.toLowerCase() === 'x-remove-user-agent') { + headers.splice(i, 2); + i -= 2; + } + } + for (let i = 0; i < headers.length; i += 2) { + const k = headers[i]; + if (typeof k === 'string' && k.toLowerCase() === 'user-agent') { + headers.splice(i, 2); + i -= 2; + } + } + }); +} /** * FetchAxios类 - HTTP客户端实现 @@ -71,6 +115,18 @@ class FetchAxios { finalConfig = await interceptor(finalConfig) || finalConfig; } + if (finalConfig.headers) { + const headerKeys = Object.keys(finalConfig.headers); + for (const key of headerKeys) { + if (key.toLowerCase() === 'user-agent' && finalConfig.headers[key] === 'RemoveUserAgent') { + delete finalConfig.headers[key]; + finalConfig.headers['x-remove-user-agent'] = '1'; + ensureUndiciStripUASubscription(); + break; + } + } + } + // 拼接查询参数 if (finalConfig.params) { const query = new URLSearchParams(finalConfig.params).toString(); @@ -300,4 +356,4 @@ export function createHttpsInstance() { responseType: 'arraybuffer', httpsAgent: httpsAgent }); -} \ No newline at end of file +} diff --git a/spider/js/_debug.js b/spider/js/_debug.js new file mode 100644 index 00000000..d32b3df1 --- /dev/null +++ b/spider/js/_debug.js @@ -0,0 +1,85 @@ +// _debug.js +// 测试方法: http://localhost:5757/api/_debug?pwd=dzyyds +var rule = { + title: '_debug', + description: '这是描述', + 类型: '测试', + searchUrl: '', + class_parse: async () => { + log(`[${rule.title}] --class_parse--`); + return [ + {type_id: '1', type_name: '电影'}, + {type_id: '2', type_name: '电视剧'}, + {type_id: '3', type_name: '综艺'}, + {type_id: '4', type_name: '动漫'}, + ] + }, + 预处理: async () => { + log(`[${rule.title}] --预处理--`); + rule.title = '_debug'; + }, + 推荐: async () => { + // return '这是推荐:' + rule.title; + let d = []; + let html = '{}'; + html = await request('https://httpbin.org/headers', { + headers: { + 'Accept': '*/*', + 'User-Agent': '' + } + }); + // log(html); + d.push({ + title: 'request结果1-传空UA', + content: html.parseX.headers, + }); + + html = await request('https://httpbin.org/headers', { + headers: { + 'Accept': '*/*', + 'User-Agent': 'RemoveUserAgent', + } + }); + // log(html); + d.push({ + title: 'request结果2-不传UA', + content: html.parseX.headers, + }); + + html = (await req('https://httpbin.org/headers', { + headers: { + 'Accept': '*/*', + 'User-Agent': 'RemoveUserAgent', + } + })).content; + d.push({ + title: 'req结果-不传UA', + content: html.parseX.headers, + }); + + html = (await req('https://conn.origjoy.com/auth/init?appid=d4eeacc6cec3434fbc8c41608a3056a0&mac=0afa691314fd_a12d4a7c9n12&sn=a12d4a7c9n12&time=1768728113&ver=2.0&vn=4.1.3.03281430&sign=6a1ee16242b93a3ae6492bc55992b691', + { + headers: { + 'Accept': '*/*', + 'User-Agent': 'RemoveUserAgent', + } + })).content; + d.push({ + title: 'req结果-60wmv', + content: html, + }); + return d; + }, + 一级: async () => { + return '这是一级:' + rule.title + }, + 二级: async () => { + return '这是二级:' + rule.title + }, + 搜索: async () => { + return ['这是搜索:' + rule.title] + }, + lazy: async () => { + return '这是播放:' + rule.title + }, +}; \ No newline at end of file diff --git a/spider/js/_lib.request.js b/spider/js/_lib.request.js index 8e9f85be..2df7a794 100644 --- a/spider/js/_lib.request.js +++ b/spider/js/_lib.request.js @@ -1,5 +1,19 @@ const iconv = require('iconv-lite'); +function sanitizeUserAgent(headers) { + if (!headers) { + return headers; + } + const keys = Object.keys(headers); + for (const key of keys) { + if (key.toLowerCase() === 'user-agent' && headers[key] === 'RemoveUserAgent') { + delete headers[key]; + break; + } + } + return headers; +} + async function requestHtml(url, options) { try { let html = (await req(url, options)).content; @@ -30,15 +44,20 @@ async function getPublicIp() { async function getHtml(config) { try { - return await axios.request(typeof config === "string" ? config : { + if (typeof config === "string") { + return await axios.request(config) + } + const cfg = { url: config.url, method: config.method || 'GET', headers: config.headers || { 'User-Agent': PC_UA }, data: config.data || '', - responseType: config.responseType || '',//'arraybuffer' - }) + responseType: config.responseType || '' + }; + cfg.headers = sanitizeUserAgent(cfg.headers); + return await axios.request(cfg) } catch (e) { return e.response } @@ -54,6 +73,7 @@ async function req_(reqUrl, mt, headers, data) { }, data: data || '', }; + config.headers = sanitizeUserAgent(config.headers); let res = await axios.request(config); return res.data; } @@ -68,6 +88,7 @@ async function req_encoding(reqUrl, mt, headers, encoding, data) { data: data || '', responseType: 'arraybuffer' }; + config.headers = sanitizeUserAgent(config.headers); let res = await axios.request(config); if (encoding) { res.data = iconv.decode(res.data, encoding); @@ -88,6 +109,7 @@ async function req_proxy(reqUrl, mt, headers, data) { port: "7890" } }; + config.headers = sanitizeUserAgent(config.headers); if (data) { config.data = data; } diff --git a/utils/createAxiosAgent.js b/utils/createAxiosAgent.js index 4c8f5599..ceb8bfdd 100644 --- a/utils/createAxiosAgent.js +++ b/utils/createAxiosAgent.js @@ -39,14 +39,27 @@ export function createAxiosInstance(options = {}) { const httpsAgent = new https.Agent(httpsAgentOptions); - // 配置 axios 使用代理 const _axios = axios.create({ - httpAgent, // 用于 HTTP 请求的代理 - httpsAgent, // 用于 HTTPS 请求的代理 + httpAgent, + httpsAgent, + }); + + _axios.interceptors.request.use(config => { + if (config && config.headers) { + const headers = config.headers; + const keys = Object.keys(headers); + for (const key of keys) { + if (key.toLowerCase() === 'user-agent' && headers[key] === 'RemoveUserAgent') { + delete headers[key]; + break; + } + } + } + return config; }); return _axios; } // 默认导出 -export default createAxiosInstance; \ No newline at end of file +export default createAxiosInstance; From de056c2092d25e38e80453b4349dbc9c2c6224f3 Mon Sep 17 00:00:00 2001 From: Taois Date: Sun, 18 Jan 2026 17:40:54 +0800 Subject: [PATCH 44/99] =?UTF-8?q?feat:=20=E9=81=BF=E5=85=8D=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E5=92=8C=E6=89=93=E5=8C=85=E4=B8=80=E4=BA=9B=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + package.js | 2 +- package.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 28c6287f..7bbca429 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,4 @@ dist /apps/salary/ /jx/_30wmv.js .DS_Store +/spider/catvod/mtv60w[差].js diff --git a/package.js b/package.js index 1e52492e..6489562d 100644 --- a/package.js +++ b/package.js @@ -7,7 +7,7 @@ import url from 'url'; const EXCLUDE_DIRS = ['.git', '.idea', 'soft', 'examples', 'apps/cat', 'plugins/pvideo', 'plugins/req-proxy', 'plugins/pup-sniffer', 'plugins/mediaProxy', 'pyTools', 'drop_code', 'jstest', 'local', 'logs', '对话1.txt', 'vod_cache', 'data/mv']; // 要排除的文件列表 -const EXCLUDE_FILES = ['config/env.json', '.env', '.claude', 'clipboard.txt', 'clipboard.txt.bak', '.plugins.js', 'yarn.lock', 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', 'json/UC分享.json', 'jx/_30wmv.js', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json']; +const EXCLUDE_FILES = ['config/env.json', '.env', '.claude', 'clipboard.txt', 'clipboard.txt.bak', '.plugins.js', 'yarn.lock', 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', 'spider/catvod/mtv60w[差].js', 'json/UC分享.json', 'jx/_30wmv.js', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json']; // 获取脚本所在目录 const getScriptDir = () => dirname(resolve(url.fileURLToPath(import.meta.url))); diff --git a/package.py b/package.py index 827deca9..d34e7011 100644 --- a/package.py +++ b/package.py @@ -16,6 +16,7 @@ EXCLUDE_FILES = ['config/env.json', '.env', '.claude', 'clipboard.txt', 'clipboard.txt.bak', '.plugins.js', 'yarn.lock', 't4_daemon.pid', 'spider/js/UC分享.js', 'spider/js/百忙无果[官].js', + 'spider/catvod/mtv60w[差].js', 'json/UC分享.json', 'jx/_30wmv.js', 'jx/奇奇.js', 'jx/芒果关姐.js', 'data/settings/link_data.json', 'index.json', 'custom.json'] From 6d5f80ec520c59948ea4d30547ba76a0472ab8d1 Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 19:26:01 +0800 Subject: [PATCH 45/99] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DhostName?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E5=85=B3=E5=A7=90=E5=9C=B0=E5=9D=80=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/file.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/utils/file.js b/utils/file.js index 07da6728..964b1dff 100644 --- a/utils/file.js +++ b/utils/file.js @@ -148,10 +148,21 @@ export function getParsesDict(host) { const jx_conf_text = readFileSync(jx_conf, 'utf-8'); let jx_conf_content = jx_conf_text.trim(); - // 准备模板变量字典 + let hostName = host; + try { + if (typeof host === 'string' && host) { + const u = new URL(host.includes('://') ? host : `http://${host}`); + hostName = u.hostname || host; + } + } catch (e) { + const withoutProto = String(host || '').replace(/^[a-zA-Z]+:\/\//, ''); + const withoutPath = withoutProto.split('/')[0]; + hostName = withoutPath.includes(':') ? withoutPath.split(':')[0] : withoutPath; + } + let var_dict = { host, - hostName: host.split(':').length > 1 ? host.slice(0, host.lastIndexOf(":")) : host + hostName }; // 使用Jinja模板引擎渲染配置内容 @@ -213,4 +224,4 @@ export function executeParse(name, host, url) { } globalThis.pathLib = pathLib; -globalThis.executeParse = executeParse; \ No newline at end of file +globalThis.executeParse = executeParse; From 968386782ad3ad0aefb79889aa14c803d28009e0 Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 19:40:18 +0800 Subject: [PATCH 46/99] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DhostName?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=94=99=E8=AF=AF=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E5=85=B3=E5=A7=90=E5=9C=B0=E5=9D=80=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/file.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/utils/file.js b/utils/file.js index 964b1dff..420e67a5 100644 --- a/utils/file.js +++ b/utils/file.js @@ -150,14 +150,15 @@ export function getParsesDict(host) { let hostName = host; try { - if (typeof host === 'string' && host) { - const u = new URL(host.includes('://') ? host : `http://${host}`); - hostName = u.hostname || host; - } + const raw = String(host || ''); + const hasScheme = raw.includes('://'); + const u = new URL(hasScheme ? raw : `http://${raw}`); + const hostname = u.hostname || raw; + const safeHostname = hostname.includes(':') ? `[${hostname}]` : hostname; + hostName = hasScheme ? `${u.protocol}//${safeHostname}` : safeHostname; } catch (e) { - const withoutProto = String(host || '').replace(/^[a-zA-Z]+:\/\//, ''); - const withoutPath = withoutProto.split('/')[0]; - hostName = withoutPath.includes(':') ? withoutPath.split(':')[0] : withoutPath; + const raw = String(host || '').replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//, '').split('/')[0]; + hostName = raw.startsWith('[') ? raw.split(']')[0] + ']' : raw.split(':')[0]; } let var_dict = { From 4a0664f8d9303d9c049dc7fa93afa136f12ace61 Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 21:14:07 +0800 Subject: [PATCH 47/99] =?UTF-8?q?feat:=E6=9B=B4=E6=96=B0=E4=B8=80=E6=B3=A2?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/parses.conf | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/config/parses.conf b/config/parses.conf index f150792d..95a61601 100644 --- a/config/parses.conf +++ b/config/parses.conf @@ -3,13 +3,14 @@ # 名称,链接,类型,ua,flag (ua不填默认 Mozilla/5.0) 可以手动填 Dart/2.14 (dart:io) # JSON解析排前面 -J1,https://zy.qiaoji8.com/gouzi.php?url=,1 -J2,https://jxjson.icu/neibu.php?url=,1 +J1,https://kalbim.xatut.top/kalbim2025/781718/play/video_player.php?url=,1 +J2,http://sspa8.top:8100/api/?key=1060089351&url=,1 # J3,http://pan.qiaoji8.com/tvbox/neibu.php?url=,1 # J4,http://yunhai.qijiyun.vip/home/api?type=ys&uid=177259&key=dijnouxKNOQSTUWXY5&url=,1 J芒果4k,http://mg.itufm.top/mg.php?url=,1 -HGvip,http://1.94.221.189:88/algorithm.php?url=,1 # J皮皮虾,http://45.207.215.101:5423/index.php?url=,1 +J腾讯关姐,{{hostName}}:5759/tencent.php/?url=,1 +# 295关姐,{{hostName}}:5759/295yun.php?url=,1 # WEB解析放后面 W花旗,https://www.huaqi.live/?url= @@ -18,15 +19,18 @@ W盘古,https://www.playm3u8.cn/jiexi.php?url= # W虾米,https://jx.xmflv.com/?url= # W无双,http://103.117.123.193:1980/players/?url= W1,https://jx.xymp4.cc/?url= -# W2,https://cdn.zyc888.top/?url= -# W3,https://yparse.ik9.cc/index.php?url= -# W4,https://jx.yparse.com/index.php?url= -# W5,https://jx.2s0.cn/player/?url= -# W6,https://jx.quankan.app/?url= +#W2,https://im1907.top/?jx= +W3,https://yparse.ik9.cc/index.php?url= +W4,https://jiexi.site/?url= +W5,https://jx.m3u8.tv/jiexi/?url= +W7,https://www.pangujiexi.com/jiexi/?url= +W8,https://www.pouyun.com/?url= +W9,https://jx.xmflv.com/?url= +Wa,https://jx.xmflv.cc/?url= +Wb,https://jx.yparse.com/index.php?url= +Wc,https://www.8090g.cn/?url= # W7,https://jx.aidouer.net/?url= # W8,https://www.8090g.cn/?url= # W9,https://jx.yangtu.top?url= # W10,https://jx.m3u8.tv/jiexi/?url= -W11,https://www.ckplayer.vip/jiexi/?url= -腾讯关姐,{{hostName}}:5759/tencent.php/?url=,1 -295关姐,{{hostName}}:5759/295yun.php?url=,1 +Wz,https://www.ckplayer.vip/jiexi/?url= From fe12e248712c5e0f6100a9e2b44aefb59e8c7c3e Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 22:39:26 +0800 Subject: [PATCH 48/99] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=8F=A6=E7=B1=BB?= =?UTF-8?q?=E5=86=99=E6=B3=95=E7=9A=84cat=E6=BA=90=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/catvod.js | 10 +- libs_drpy/drpyInject.js | 50 ++- ...\345\223\251\345\223\251[\345\256\230].js" | 323 ++++++++++++++ ...\345\244\256\345\244\256[\345\256\230].js" | 290 +++++++++++++ ...\345\245\207\345\245\207[\345\256\230].js" | 403 ++++++++++++++++++ ...\346\236\234\346\236\234[\345\256\230].js" | 365 ++++++++++++++++ ...\351\205\267\351\205\267[\345\256\230].js" | 356 ++++++++++++++++ 7 files changed, 1792 insertions(+), 5 deletions(-) create mode 100644 "spider/catvod/\345\223\251\345\223\251[\345\256\230].js" create mode 100644 "spider/catvod/\345\244\256\345\244\256[\345\256\230].js" create mode 100644 "spider/catvod/\345\245\207\345\245\207[\345\256\230].js" create mode 100644 "spider/catvod/\346\236\234\346\236\234[\345\256\230].js" create mode 100644 "spider/catvod/\351\205\267\351\205\267[\345\256\230].js" diff --git a/libs/catvod.js b/libs/catvod.js index efb465cf..e9228e3c 100644 --- a/libs/catvod.js +++ b/libs/catvod.js @@ -184,10 +184,16 @@ const category = async function (filePath, env, tid, pg = 1, filter = 1, extend const detail = async function (filePath, env, ids) { const moduleObject = await init(filePath, env); const vod_id = Array.isArray(ids) ? ids[0] : ids; - return json2Object(await moduleObject.detail(vod_id)); + let detailResult = '{}'; + // console.log('type of detailContent:', typeof moduleObject.detailContent); + if (moduleObject.detailContent) { // tvbox形式猫源二级参数传ids列表 + detailResult = await moduleObject.detailContent(ids); + } else { // ds/cat传非id + detailResult = await moduleObject.detail(vod_id); + } + return json2Object(detailResult); } - const search = async function (filePath, env, wd, quick = 0, pg = 1) { const moduleObject = await init(filePath, env); return json2Object(await moduleObject.search(wd, quick, pg)); diff --git a/libs_drpy/drpyInject.js b/libs_drpy/drpyInject.js index 75d25c8c..b473ec13 100644 --- a/libs_drpy/drpyInject.js +++ b/libs_drpy/drpyInject.js @@ -163,10 +163,10 @@ async function request(url, opt = {}) { let effectivePostType = postType; if (!effectivePostType) { // 查找不区分大小写的 Content-Type 头 - const contentTypeKey = Object.keys(headers).find(key => + const contentTypeKey = Object.keys(headers).find(key => key.toLowerCase() === 'content-type' ); - + if (contentTypeKey && headers[contentTypeKey]) { const contentType = headers[contentTypeKey].toLowerCase(); if (contentType.includes('application/x-www-form-urlencoded')) { @@ -176,7 +176,7 @@ async function request(url, opt = {}) { } } } - + // 根据有效的 postType 处理数据 if (effectivePostType === 'form' && data != null && typeof data === 'object') { data = qs.stringify(data, {encode: false}); @@ -724,4 +724,48 @@ globalThis.jsonToCookie = jsonToCookie; globalThis.cookieToJson = cookieToJson; globalThis.keysToLowerCase = keysToLowerCase; +class BaseSpider { + constructor() { + this.home = this.homeContent; + this.category = this.categoryContent; + // this.detail = this.detailContent; + this.search = this.searchContent; + this.play = this.playerContent; + this.homeVod = this.homeVideoContent; + this.proxy = this.localProxy; + } + + async fetch(url, options) { + const content = (await req(url, options)).content; + return {data: content.parseX}; + } + + async homeContent() { + } + + async categoryContent() { + } + + async detailContent() { + } + + async searchContent() { + } + + async playerContent() { + } + + async homeVideoContent() { + } + + async localProxy() { + + } + + async action() { + + } +} + +globalThis.BaseSpider = BaseSpider; export default {}; diff --git "a/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" "b/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" new file mode 100644 index 00000000..df164c9c --- /dev/null +++ "b/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" @@ -0,0 +1,323 @@ +/** + * 哔哩哔哩 - 猫影视JS爬虫格式 + * 调用壳子超级解析功能 + @header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: 'B站', + lang: 'cat' + }) + */ + +class Spider extends BaseSpider { + + constructor() { + super(); + this.host = 'https://www.bilibili.com'; + this.headers = { + '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', + 'Referer': 'https://www.bilibili.com', + 'Accept': 'application/json, text/plain, */*', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' + }; + + // B站Cookie(需要登录才能获取高清画质) + this.cookie = ""; + this.isLoggedIn = () => { + return this.cookie && this.cookie.includes("SESSDATA="); + }; + } + + init(extend = '') { + return ''; + } + + getName() { + return '哔哩哔哩'; + } + + isVideoFormat(url) { + return true; + } + + manualVideoCheck() { + return false; + } + + destroy() { + // 清理资源 + } + + homeContent(filter) { + const classes = [ + {type_id: '1', type_name: '番剧'}, + {type_id: '4', type_name: '国创'}, + {type_id: '2', type_name: '电影'}, + {type_id: '5', type_name: '电视剧'}, + {type_id: '3', type_name: '纪录片'}, + {type_id: '7', type_name: '综艺'} + ]; + + return { + class: classes + }; + } + + homeVideoContent() { + return {list: []}; + } + + async categoryContent(tid, pg, filter, extend) { + try { + const page = parseInt(pg) || 1; + let url = ''; + + if (['1', '4'].includes(tid)) { + url = `https://api.bilibili.com/pgc/web/rank/list?season_type=${tid}&pagesize=20&page=${page}&day=3`; + } else { + url = `https://api.bilibili.com/pgc/season/rank/web/list?season_type=${tid}&pagesize=20&page=${page}&day=3`; + } + + const headers = {...this.headers}; + if (this.cookie) { + headers.Cookie = this.cookie; + } + + const response = await this.fetch(url, {}, headers); + const data = response.data || {}; + + const videos = []; + if (data.code === 0) { + const vodList = data.result ? data.result.list : (data.data ? data.data.list : []); + + for (const vod of vodList) { + const title = vod.title ? vod.title.trim() : ''; + if (title.includes('预告')) { + continue; + } + + const remark = vod.new_ep ? vod.new_ep.index_show : vod.index_show; + + // 处理封面图片 + let cover = vod.cover || ''; + if (cover && cover.startsWith('//')) { + cover = 'https:' + cover; + } + + videos.push({ + vod_id: vod.season_id ? vod.season_id.toString() : '', + vod_name: title, + vod_pic: cover, + vod_remarks: remark || '' + }); + } + } + + return { + list: videos, + page: page, + pagecount: videos.length === 20 ? page + 1 : page, + limit: 20, + total: 9999 + }; + + } catch (error) { + console.error(`categoryContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + formatCount(num) { + if (num > 1e8) return (num / 1e8).toFixed(2) + '亿'; + if (num > 1e4) return (num / 1e4).toFixed(2) + '万'; + return num.toString(); + } + + async detailContent(ids) { + try { + const seasonId = ids[0]; + + const headers = {...this.headers}; + if (this.cookie) { + headers.Cookie = this.cookie; + } + + const url = `https://api.bilibili.com/pgc/view/web/season?season_id=${seasonId}`; + const response = await this.fetch(url, {}, headers); + const data = response.data || {}; + + if (data.code !== 0) { + return {list: []}; + } + + const res = data.result; + const stat = res.stat || {}; + + // 处理封面图片 + let cover = res.cover || ''; + if (cover && cover.startsWith('//')) { + cover = 'https:' + cover; + } + + const vod = { + vod_id: res.season_id ? res.season_id.toString() : '', + vod_name: res.title || '', + vod_pic: cover, + type_name: res.share_sub_title || res.type_name || '', + vod_year: res.publish && res.publish.pub_time ? res.publish.pub_time.substr(0, 4) : '', + vod_area: res.areas && res.areas.length > 0 ? res.areas[0].name : '', + vod_actor: `点赞:${this.formatCount(stat.likes || 0)} 投币:${this.formatCount(stat.coins || 0)}`, + vod_content: res.evaluate || res.new_ep?.desc || '', + vod_director: res.rating ? `评分:${res.rating.score}` : '暂无评分', + vod_play_from: '哔哩哔哩', + vod_play_url: '' + }; + + // 过滤预告片,构建播放列表 + const episodes = (res.episodes || []).filter(ep => !ep.title.includes('预告')); + const playUrls = []; + + for (const ep of episodes) { + const title = `${ep.title.replace(/#/g, '-')} ${ep.long_title || ''}`; + const playId = `${res.season_id}_${ep.id}_${ep.cid}`; + playUrls.push(`${title}$${playId}`); + } + + vod.vod_play_url = playUrls.join('#'); + + return {list: [vod]}; + + } catch (error) { + console.error(`detailContent error: ${error.message}`); + return {list: []}; + } + } + + async searchContent(key, quick, pg = '1') { + try { + const page = parseInt(pg) || 1; + const encodedKeyword = encodeURIComponent(key); + const searchTypes = ['media_bangumi', 'media_ft']; + + const headers = {...this.headers}; + if (this.cookie) { + headers.Cookie = this.cookie; + } + + const allVideos = []; + + for (const type of searchTypes) { + try { + const url = `https://api.bilibili.com/x/web-interface/search/type?search_type=${type}&keyword=${encodedKeyword}&page=${page}`; + const response = await this.fetch(url, {}, headers); + const data = response.data || {}; + + if (data.code === 0 && data.data && data.data.result) { + for (const vod of data.data.result) { + const title = vod.title ? vod.title.replace(/<[^>]+>/g, '') : ''; + if (title.includes('预告')) { + continue; + } + + // 处理封面图片 + let cover = vod.cover || ''; + if (cover && cover.startsWith('//')) { + cover = 'https:' + cover; + } + + allVideos.push({ + vod_id: vod.season_id ? vod.season_id.toString() : '', + vod_name: title, + vod_pic: cover, + vod_remarks: vod.index_show || '' + }); + } + } + } catch (searchError) { + console.error(`搜索类型 ${type} 失败: ${searchError.message}`); + } + } + + return { + list: allVideos, + page: page, + pagecount: allVideos.length > 0 ? page + 1 : page, + limit: 20, + total: allVideos.length + }; + + } catch (error) { + console.error(`searchContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async playerContent(flag, id, vipFlags) { + try { + // 哔哩哔哩有自己的解析逻辑,直接返回播放链接 + // 格式:seasonId_epId_cid + const parts = id.split('_'); + if (parts.length < 3) { + throw new Error('无效的播放ID格式'); + } + + const seasonId = parts[0]; + const epId = parts[1]; + const cid = parts[2]; + + // 构建播放链接(原版B站链接) + const playUrl = `https://www.bilibili.com/bangumi/play/ep${epId}`; + + // 调用壳子超级解析 + const playData = { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '哔哩哔哩', + url: playUrl, + header: JSON.stringify({ + 'User-Agent': this.headers['User-Agent'], + 'Referer': 'https://www.bilibili.com', + 'Origin': 'https://www.bilibili.com', + 'Cookie': this.cookie || '' + }) + }; + + return playData; + + } catch (error) { + console.error(`playerContent error: ${error.message}`); + // 即使出错也返回超级解析参数 + return { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '哔哩哔哩', + url: id.includes('_') ? `https://www.bilibili.com/bangumi/play/ep${id.split('_')[1]}` : id, + header: JSON.stringify(this.headers) + }; + } + } + + localProxy(param) { + return null; + } +} + + +export default new Spider(); \ No newline at end of file diff --git "a/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" "b/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" new file mode 100644 index 00000000..895aea15 --- /dev/null +++ "b/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" @@ -0,0 +1,290 @@ +/** + * 央视大全 - 猫影视/TVBox JS爬虫格式 + * 继承BaseSpider类 + @header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '央视大全', + lang: 'cat' + }) + */ + +class Spider extends BaseSpider { + + constructor() { + super(); + this.host = 'https://api.cntv.cn'; + this.siteName = '央视大全'; + this.sessionStore = {}; + this.videoCache = {}; + + this.headers = { + "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", + "Referer": "https://tv.cctv.com", + "Accept": "application/json, text/plain, */*", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8" + }; + } + + init(extend = "") { + return ""; + } + + getName() { + return this.siteName; + } + + isVideoFormat(url) { + return url.includes('.m3u8') || url.includes('.mp4'); + } + + manualVideoCheck() { + return false; + } + + destroy() { + this.sessionStore = {}; + this.videoCache = {}; + } + + homeContent(filter) { + const categories = [ + {type_id: "栏目大全", type_name: "栏目大全"}, + {type_id: "特别节目", type_name: "特别节目"}, + {type_id: "纪录片", type_name: "纪录片"}, + {type_id: "电视剧", type_name: "电视剧"}, + {type_id: "动画片", type_name: "动画片"} + ]; + + return {class: categories}; + } + + async homeVideoContent() { + // 央视首页推荐 + return {list: []}; + } + + async categoryContent(tid, pg, filter, extend) { + try { + const page = parseInt(pg) || 1; + const videos = []; + + const channelMap = { + "特别节目": "CHAL1460955953877151", + "纪录片": "CHAL1460955924871139", + "电视剧": "CHAL1460955853485115", + "动画片": "CHAL1460955899450127", + }; + + let filterObj = {}; + if (extend && typeof extend === 'object') { + filterObj = extend; + } + + if (tid === '栏目大全') { + const url = `${this.host}/lanmu/columnSearch?&fl=&fc=&cid=&p=${page}&n=20&serviceId=tvcctv&t=json`; + const response = await this.fetch(url, {}, this.headers); + const data = response.data; + + if (data && data.response && data.response.docs) { + const docs = data.response.docs; + docs.forEach(it => { + videos.push({ + vod_id: `${it.lastVIDE.videoSharedCode}|${it.column_firstclass}|${it.column_name}|${it.channel_name}|${it.column_brief}|${it.column_logo}|${it.lastVIDE.videoTitle}|栏目大全`, + vod_name: it.column_name, + vod_pic: it.column_logo, + vod_remarks: it.channel_name, + vod_content: '' + }); + }); + } + } else { + // 处理筛选参数 + let fl_url = `&channelid=${channelMap[tid] || ''}&fc=${encodeURIComponent(tid)}`; + if (filterObj.channel) fl_url += `&channel=${encodeURIComponent(filterObj.channel)}`; + if (filterObj.sc) fl_url += `&sc=${encodeURIComponent(filterObj.sc)}`; + if (filterObj.year) fl_url += `&year=${filterObj.year}`; + + const url = `${this.host}/list/getVideoAlbumList?${fl_url}&area=&letter=&n=24&serviceId=tvcctv&t=json&p=${page}`; + const response = await this.fetch(url, {}, this.headers); + const data = response.data; + + if (data && data.data && data.data.list) { + const dataList = data.data.list; + dataList.forEach(it => { + videos.push({ + vod_id: `${it.id}|${it.sc}|${it.title}|${it.channel}|${it.brief}|${it.image}|${it.count}|${tid}`, + vod_name: it.title, + vod_pic: it.image, + vod_remarks: `${it.sc}${it.year ? '·' + it.year : ''}`, + vod_content: it.brief || '' + }); + }); + } + } + + return { + list: videos, + page: page, + pagecount: 9999, + limit: 20, + total: 999999 + }; + + } catch (error) { + console.error(`categoryContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async detailContent(ids) { + try { + const id = ids[0]; + if (!id) return {list: []}; + + // 检查缓存 + const cacheKey = `detail_${id}`; + if (this.videoCache[cacheKey]) { + return {list: [this.videoCache[cacheKey]]}; + } + + const info = id.split("|"); + // ID 结构: 0:id, 1:sc, 2:title, 3:channel, 4:brief, 5:image, 6:count/remark, 7:cate + + const cate = info[7]; + const ctid = info[0]; + const modeMap = { + "特别节目": "0", + "纪录片": "0", + "电视剧": "0", + "动画片": "1" + }; + + // 获取选集列表 + let playUrls = []; + const mode = modeMap[cate] || '0'; + const albumUrl = `${this.host}/NewVideo/getVideoListByAlbumIdNew?id=${ctid}&serviceId=tvcctv&p=1&n=100&mode=${mode}&pub=1`; + + const response = await this.fetch(albumUrl, {}, this.headers); + const data = response.data; + + if (data.errcode === '1001') { + // 需要获取真实的ctid + const videoInfoUrl = `${this.host}/video/videoinfoByGuid?guid=${ctid}&serviceId=tvcctv`; + const vInfoRes = await this.fetch(videoInfoUrl, {}, this.headers); + const vInfoData = vInfoRes.data; + const realCtid = vInfoData.ctid; + + const columnUrl = `${this.host}/NewVideo/getVideoListByColumn?id=${realCtid}&d=&p=1&n=100&sort=desc&mode=0&serviceId=tvcctv&t=json`; + const colRes = await this.fetch(columnUrl, {}, this.headers); + const colData = colRes.data; + playUrls = colData.data?.list || []; + } else { + playUrls = data.data?.list || []; + } + + // 构建播放列表 + const playList = []; + if (playUrls.length > 0) { + for (const item of playUrls) { + const title = item.title || `第${item.index || '?'}集`; + const cleanTitle = title.replace(/\$/g, ''); + const guid = item.guid || ''; + playList.push(`${cleanTitle}$${guid}`); + } + } + + const vod = { + vod_id: id, + vod_name: info[2] || '', + vod_pic: info[5] || '', + type_name: info[1] || '', + vod_year: '', + vod_area: '', + vod_remarks: info[6] ? `共${info[6]}集` : '', + vod_actor: '', + vod_director: '', + vod_content: info[4] || '', + vod_play_from: playList.length > 0 ? '央视频' : '', + vod_play_url: playList.length > 0 ? playList.join('#') : '' + }; + + // 缓存结果 + this.videoCache[cacheKey] = vod; + + return {list: [vod]}; + + } catch (error) { + console.error(`detailContent error: ${error.message}`); + return {list: []}; + } + } + + async searchContent(key, quick, pg = "1") { + // CCTV搜索接口较复杂,这里返回空结果 + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + + async playerContent(flag, id, vipFlags) { + try { + // 央视视频采用直接播放的方式 + // 根据GUID拼接m3u8地址 + let playUrl = `https://cntv.playdreamer.cn/proxy/asp/hls/2000/0303000a/3/default/${id}/2000.m3u8`; + + // 也可以尝试其他格式 + // playUrl = `https://hls.cntv.myalicdn.com/asp/hls/2000/0303000a/3/default/${id}/2000.m3u8`; + + return { + parse: 0, // 0表示直接播放,不需要解析 + jx: 0, // 0表示不解析 + url: playUrl, + header: JSON.stringify({ + 'User-Agent': this.headers['User-Agent'], + 'Referer': 'https://tv.cctv.com', + 'Origin': 'https://tv.cctv.com' + }) + }; + + } catch (error) { + console.error(`playerContent error: ${error.message}`); + return { + parse: 0, + jx: 0, + url: id, + header: JSON.stringify(this.headers) + }; + } + } + + localProxy(param) { + return null; + } + + // 辅助方法:安全获取对象属性 + getSafe(obj, path, defaultValue = '') { + if (!obj || typeof obj !== 'object') return defaultValue; + try { + return path.split('.').reduce((o, key) => { + if (o == null) return defaultValue; + return o[key]; + }, obj) ?? defaultValue; + } catch { + return defaultValue; + } + } +} + +export default new Spider(); \ No newline at end of file diff --git "a/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" "b/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" new file mode 100644 index 00000000..956ed6b1 --- /dev/null +++ "b/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" @@ -0,0 +1,403 @@ +/** + * 爱奇艺视频 - 猫影视/TVBox JS爬虫格式 + * 调用壳子超级解析功能(壳子会自动读取json配置) + @header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '爱奇艺视频', + lang: 'cat' + }) + */ + +class Spider extends BaseSpider { + + constructor() { + super(); + this.host = 'https://www.iqiyi.com'; + this.sessionStore = {}; + + this.headers = { + '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', + 'Referer': 'https://www.iqiyi.com', + 'Accept': 'application/json, text/plain, */*', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Connection': 'keep-alive' + }; + + // 分类配置 + this.classes = [ + {type_id: '1', type_name: '电影'}, + {type_id: '2', type_name: '电视剧'}, + {type_id: '6', type_name: '综艺'}, + {type_id: '4', type_name: '动漫'}, + {type_id: '3', type_name: '纪录片'}, + {type_id: '5', type_name: '音乐'}, + {type_id: '16', type_name: '网络电影'} + ]; + + // 筛选配置 + this.filters = { + '1': [{ + key: 'year', + name: '年代', + value: [{n: '全部', v: ''}, {n: '2025', v: '2025'}, {n: '2024', v: '2024'}, {n: '2023', v: '2023'}] + }], + '2': [{ + key: 'year', + name: '年代', + value: [{n: '全部', v: ''}, {n: '2025', v: '2025'}, {n: '2024', v: '2024'}, {n: '2023', v: '2023'}] + }] + }; + } + + init(extend = '') { + return ''; + } + + getName() { + return '爱奇艺视频'; + } + + isVideoFormat(url) { + return true; + } + + manualVideoCheck() { + return false; + } + + destroy() { + // 清理资源 + } + + homeContent(filter) { + const result = { + class: this.classes, + filters: this.filters + }; + + return result; + } + + homeVideoContent() { + return {list: []}; + } + + async categoryContent(tid, pg, filter, extend) { + try { + let channelId = tid; + let dataType = 1; + let extraParams = ""; + const page = parseInt(pg) || 1; + + if (tid === "16") { + channelId = "1"; + extraParams = "&three_category_id=27401"; + } else if (tid === "5") { + dataType = 2; + } + + // 处理筛选条件 + if (extend) { + let extendObj = {}; + if (typeof extend === 'string') { + try { + extendObj = JSON.parse(extend); + } catch (e) { + // 如果不是JSON,尝试解析为key=value格式 + extend.split('&').forEach(item => { + const [key, value] = item.split('='); + if (key && value) { + extendObj[key] = value; + } + }); + } + } else if (typeof extend === 'object') { + extendObj = extend; + } + + if (extendObj.year) { + extraParams += `&market_release_date_level=${extendObj.year}`; + } + } + + const url = `https://pcw-api.iqiyi.com/search/recommend/list?channel_id=${channelId}&data_type=${dataType}&page_id=${page}&ret_num=20${extraParams}`; + + const response = await this.fetch(url, {}, this.headers); + const jsonData = response.data; + + const videos = []; + if (jsonData.data && jsonData.data.list) { + for (const item of jsonData.data.list) { + const vid = `${item.channelId}$${item.albumId}`; + let remarks = ""; + + if (item.channelId === 1) { + remarks = item.score ? `${item.score}分` : ""; + } else if (item.channelId === 2 || item.channelId === 4) { + if (item.latestOrder && item.videoCount) { + remarks = item.latestOrder === item.videoCount ? + `${item.latestOrder}集全` : + `更新至${item.latestOrder}集`; + } else { + remarks = item.focus || ""; + } + } else { + remarks = item.period || item.focus || ""; + } + + videos.push({ + vod_id: vid, + vod_name: item.name, + vod_pic: item.imageUrl ? item.imageUrl.replace(".jpg", "_390_520.jpg") : "", + vod_remarks: remarks + }); + } + } + + return { + list: videos, + page: page, + pagecount: 9999, + limit: 20, + total: 999999 + }; + + } catch (error) { + console.error(`categoryContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async getPlaylists(channelId, albumId, data) { + let playlists = []; + const cid = parseInt(channelId || data.channelId || 0); + + try { + if (cid === 1 || cid === 5) { + // 电影或音乐 + if (data.playUrl) { + playlists.push({title: data.name || '正片', url: data.playUrl}); + } + } else if (cid === 6 && data.period) { + // 综艺 + let qs = data.period.toString().split("-")[0]; + let listUrl = `https://pcw-api.iqiyi.com/album/source/svlistinfo?cid=6&sourceid=${albumId}&timelist=${qs}`; + try { + const listResp = await this.fetch(listUrl, {}, this.headers); + const listJson = listResp.data; + if (listJson.data && listJson.data[qs]) { + listJson.data[qs].forEach(it => { + playlists.push({ + title: it.shortTitle || it.period || it.focus || `期${it.order}`, + url: it.playUrl + }); + }); + } + } catch (e) { + console.error(`综艺列表获取失败: ${e.message}`); + } + } else { + // 电视剧、动漫等 + let listUrl = `https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid=${albumId}&size=100&page=1`; + try { + const listResp = await this.fetch(listUrl, {}, this.headers); + const listJson = listResp.data; + + if (listJson.data && listJson.data.epsodelist) { + playlists = listJson.data.epsodelist.map(item => ({ + title: item.shortTitle || item.title || + (item.order ? `第${item.order}集` : `集${item.timelist}`), + url: item.playUrl || item.url || '' + })); + + // 处理分页 + const total = listJson.data.total; + if (total > 100) { + const totalPages = Math.ceil(total / 100); + for (let i = 2; i <= totalPages; i++) { + let nextUrl = `https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid=${albumId}&size=100&page=${i}`; + try { + const nextResp = await this.fetch(nextUrl, {}, this.headers); + const nextJson = nextResp.data; + if (nextJson.data && nextJson.data.epsodelist) { + playlists = playlists.concat(nextJson.data.epsodelist.map(item => ({ + title: item.shortTitle || item.title || + (item.order ? `第${item.order}集` : `集${item.timelist}`), + url: item.playUrl || item.url || '' + }))); + } + } catch (e) { + break; + } + } + } + } + } catch (e) { + console.error(`剧集列表获取失败: ${e.message}`); + } + } + } catch (error) { + console.error(`getPlaylists error: ${error.message}`); + } + + return playlists; + } + + async detailContent(ids) { + try { + const id = ids[0]; + let channelId = ""; + let albumId = id; + + if (id.includes('$')) { + const parts = id.split('$'); + channelId = parts[0]; + albumId = parts[1]; + } + + // 获取视频基本信息 + const infoUrl = `https://pcw-api.iqiyi.com/video/video/videoinfowithuser/${albumId}?agent_type=1&authcookie=&subkey=${albumId}&subscribe=1`; + const infoResp = await this.fetch(infoUrl, {}, this.headers); + const infoJson = infoResp.data; + const data = infoJson.data || {}; + + // 获取播放列表 + const playlists = await this.getPlaylists(channelId, albumId, data); + + // 构建播放地址 + const playUrls = []; + if (playlists.length > 0) { + for (const item of playlists) { + if (item.url) { + playUrls.push(`${item.title}$${item.url}`); + } + } + } + + const vod = { + vod_id: id, + vod_name: data.name || '未知标题', + type_name: data.categories ? data.categories.map(it => it.name).join(',') : '', + vod_year: data.formatPeriod || '', + vod_area: data.areas ? data.areas.map(it => it.name).join(',') : '', + vod_remarks: data.latestOrder ? + `更新至${data.latestOrder}集` : + (data.period || playlists.length > 0 ? `${playlists.length}集` : ''), + vod_actor: data.people && data.people.main_charactor ? + data.people.main_charactor.map(it => it.name).join(',') : '', + vod_director: data.people && data.people.director ? + data.people.director.map(it => it.name).join(',') : '', + vod_content: data.description || '暂无简介', + vod_pic: data.imageUrl ? data.imageUrl.replace(".jpg", "_480_270.jpg") : '', + vod_play_from: playUrls.length > 0 ? '爱奇艺视频' : '', + vod_play_url: playUrls.length > 0 ? playUrls.join('#') : '' + }; + + return {list: [vod]}; + + } catch (error) { + console.error(`detailContent error: ${error.message}`); + return {list: []}; + } + } + + async searchContent(key, quick, pg = '1') { + try { + const page = parseInt(pg) || 1; + const url = `https://search.video.iqiyi.com/o?if=html5&key=${encodeURIComponent(key)}&pageNum=${page}&pos=1&pageSize=20&site=iqiyi`; + + const response = await this.fetch(url, {}, this.headers); + const jsonData = response.data; + + const videos = []; + + if (jsonData.data && jsonData.data.docinfos) { + for (const item of jsonData.data.docinfos) { + if (item.albumDocInfo) { + const doc = item.albumDocInfo; + const channelId = doc.channel ? doc.channel.split(',')[0] : '0'; + videos.push({ + vod_id: `${channelId}$${doc.albumId}`, + vod_name: doc.albumTitle || '', + vod_pic: doc.albumVImage || '', + vod_remarks: doc.tvFocus || doc.year || '' + }); + } + } + } + + return { + list: videos, + page: page, + pagecount: 10, + limit: 20, + total: videos.length + }; + + } catch (error) { + console.error(`searchContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async playerContent(flag, id, vipFlags) { + try { + // 解析播放地址 + let playUrl = id; + if (id.includes('$')) { + playUrl = id.split('$')[1]; + } + + // 关键:调用壳子超级解析 + const playData = { + parse: 1, // 必须为1,表示需要解析 + jx: 1, // 必须为1,启用解析 + play_parse: true, // 启用播放解析 + parse_type: '壳子超级解析', + parse_source: '爱奇艺视频', + url: playUrl, // 原始爱奇艺链接 + header: JSON.stringify({ + 'User-Agent': this.headers['User-Agent'], + 'Referer': 'https://www.iqiyi.com', + 'Origin': 'https://www.iqiyi.com' + }) + }; + + return playData; + + } catch (error) { + console.error(`playerContent error: ${error.message}`); + // 即使出错也返回超级解析参数,让壳子处理 + return { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '爱奇艺视频', + url: id, + header: JSON.stringify(this.headers) + }; + } + } + + localProxy(param) { + return null; + } +} + +export default new Spider(); \ No newline at end of file diff --git "a/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" "b/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" new file mode 100644 index 00000000..33f6e159 --- /dev/null +++ "b/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" @@ -0,0 +1,365 @@ +/** + * 芒果TV - 猫影视JS爬虫格式(第二个版本) + * 调用壳子超级解析功能 + @header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '芒果TV', + lang: 'cat' + }) + */ + +class Spider extends BaseSpider { + + constructor() { + super(); + this.host = 'https://www.mgtv.com'; + this.headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', + 'Referer': 'https://www.mgtv.com/', + 'Accept': 'application/json, text/plain, */*', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Connection': 'keep-alive' + }; + } + + init(extend = '') { + return ''; + } + + getName() { + return '芒果TV2'; + } + + isVideoFormat(url) { + return true; + } + + manualVideoCheck() { + return false; + } + + destroy() { + // 清理资源 + } + + homeContent(filter) { + const classes = [ + {type_id: '3', type_name: '电影'}, + {type_id: '2', type_name: '电视剧'}, + {type_id: '1', type_name: '综艺'}, + {type_id: '50', type_name: '动漫'}, + {type_id: '51', type_name: '纪录片'}, + {type_id: '115', type_name: '教育'}, + {type_id: '10', type_name: '少儿'} + ]; + + const filters = { + '3': [ + { + key: 'year', name: '年份', value: [ + {n: '全部', v: 'all'}, {n: '2025', v: '2025'}, {n: '2024', v: '2024'}, + {n: '2023', v: '2023'}, {n: '2022', v: '2022'}, {n: '2021', v: '2021'}, + {n: '2020', v: '2020'}, {n: '2019', v: '2019'}, {n: '2010-2019', v: '2010-2019'}, + {n: '2000-2009', v: '2000-2009'} + ] + }, + { + key: 'sort', name: '排序', value: [ + {n: '综合', v: 'c1'}, {n: '最新', v: 'c2'}, {n: '最热', v: 'c4'} + ] + } + ], + '2': [ + { + key: 'year', name: '年份', value: [ + {n: '全部', v: 'all'}, {n: '2025', v: '2025'}, {n: '2024', v: '2024'}, + {n: '2023', v: '2023'}, {n: '2022', v: '2022'}, {n: '2021', v: '2021'}, + {n: '2020', v: '2020'} + ] + }, + { + key: 'sort', name: '排序', value: [ + {n: '综合', v: 'c1'}, {n: '最新', v: 'c2'}, {n: '最热', v: 'c4'} + ] + } + ], + '1': [ + { + key: 'sort', name: '排序', value: [ + {n: '综合', v: 'c1'}, {n: '最新', v: 'c2'}, {n: '最热', v: 'c4'} + ] + } + ], + '50': [ + { + key: 'sort', name: '排序', value: [ + {n: '综合', v: 'c1'}, {n: '最新', v: 'c2'}, {n: '最热', v: 'c4'} + ] + } + ] + }; + + return { + class: classes, + filters: filters + }; + } + + homeVideoContent() { + return {list: []}; + } + + async categoryContent(tid, pg, filter, extend) { + try { + const page = parseInt(pg) || 1; + const baseUrl = 'https://pianku.api.mgtv.com/rider/list/pcweb/v3'; + + // 构建查询参数 + const params = { + platform: 'pcweb', + channelId: tid, + pn: page, + pc: '20', + hudong: '1', + _support: '10000000', + kind: 'a1', + area: 'a1' + }; + + // 处理筛选条件 + if (extend) { + if (extend.year && extend.year !== 'all') { + params.year = extend.year; + } + if (extend.sort) { + params.sort = extend.sort; + } + if (extend.chargeInfo) { + params.chargeInfo = extend.chargeInfo; + } + } + + const queryString = new URLSearchParams(params).toString(); + const url = `${baseUrl}?${queryString}`; + + const response = await this.fetch(url, {}, this.headers); + const json = response.data || {}; + + const videos = []; + if (json.data?.hitDocs && Array.isArray(json.data.hitDocs)) { + for (const item of json.data.hitDocs) { + videos.push({ + vod_id: item.playPartId || '', + vod_name: item.title || '', + vod_pic: item.img || '', + vod_remarks: item.updateInfo || item.rightCorner?.text || '' + }); + } + } + + return { + list: videos, + page: page, + pagecount: json.data?.totalPage || 999, + limit: 20, + total: json.data?.totalHit || 9999 + }; + + } catch (error) { + console.error(`categoryContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async detailContent(ids) { + try { + const videoId = ids[0]; + + // 获取视频基本信息 + const infoUrl = `https://pcweb.api.mgtv.com/video/info?video_id=${videoId}`; + const infoResponse = await this.fetch(infoUrl, {}, this.headers); + const infoData = infoResponse.data?.data?.info || {}; + + const vod = { + vod_id: videoId, + vod_name: infoData.title || '', + type_name: infoData.root_kind || '', + vod_actor: '', + vod_year: infoData.release_time || '', + vod_content: infoData.desc || '', + vod_remarks: infoData.time || '', + vod_pic: infoData.img || '', + vod_play_from: '芒果TV', + vod_play_url: '' + }; + + // 分页获取所有剧集 + const pageSize = 50; + let allEpisodes = []; + + try { + // 获取第一页,同时获取总页数 + const firstPageUrl = `https://pcweb.api.mgtv.com/episode/list?video_id=${videoId}&page=1&size=${pageSize}`; + const firstResponse = await this.fetch(firstPageUrl, {}, this.headers); + const firstData = firstResponse.data?.data || {}; + + if (firstData.list && Array.isArray(firstData.list)) { + allEpisodes = allEpisodes.concat(firstData.list); + const totalPages = firstData.total_page || 1; + + // 如果有多页,获取剩余页面 + if (totalPages > 1) { + const pagePromises = []; + for (let i = 2; i <= totalPages; i++) { + const pageUrl = `https://pcweb.api.mgtv.com/episode/list?video_id=${videoId}&page=${i}&size=${pageSize}`; + pagePromises.push(this.fetch(pageUrl, {}, this.headers)); + } + + const responses = await Promise.all(pagePromises); + for (const response of responses) { + const data = response.data?.data || {}; + if (data.list && Array.isArray(data.list)) { + allEpisodes = allEpisodes.concat(data.list); + } + } + } + } + } catch (episodeError) { + console.error(`获取剧集列表失败: ${episodeError.message}`); + } + + // 构建播放列表 + const playUrls = []; + if (allEpisodes.length > 0) { + // 过滤可播放的剧集(isIntact = 1) + const validEpisodes = allEpisodes.filter(item => + item.isIntact === "1" || item.isIntact === 1 + ); + + // 按集数排序 + validEpisodes.sort((a, b) => { + const orderA = parseInt(a.order) || 0; + const orderB = parseInt(b.order) || 0; + return orderA - orderB; + }); + + // 构建播放链接 + for (const item of validEpisodes) { + const name = item.t4 || item.t3 || item.title || `第${item.order || '?'}集`; + const playLink = item.url ? `https://www.mgtv.com${item.url}` : ''; + + if (playLink) { + playUrls.push(`${name}$${playLink}`); + } + } + } + + vod.vod_play_url = playUrls.join('#'); + + return {list: [vod]}; + + } catch (error) { + console.error(`detailContent error: ${error.message}`); + return {list: []}; + } + } + + async searchContent(key, quick, pg = '1') { + try { + const page = parseInt(pg) || 1; + const searchUrl = `https://mobileso.bz.mgtv.com/msite/search/v2?q=${encodeURIComponent(key)}&pn=${page}&pc=20`; + + const response = await this.fetch(searchUrl, {}, this.headers); + const json = response.data?.data || {}; + + const videos = []; + + if (json.contents && Array.isArray(json.contents)) { + for (const group of json.contents) { + if (group.type === 'media' && group.data && Array.isArray(group.data)) { + for (const item of group.data) { + if (item.source === 'imgo') { + // 提取视频ID + const match = item.url.match(/\/(\d+)\.html/); + if (match) { + videos.push({ + vod_id: match[1], + vod_name: item.title ? item.title.replace(/|<\/B>/g, '') : '', + vod_pic: item.img || '', + vod_remarks: item.desc ? item.desc.join(' ') : '' + }); + } + } + } + } + } + } + + return { + list: videos, + page: page, + pagecount: 10, + limit: 20, + total: videos.length + }; + + } catch (error) { + console.error(`searchContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async playerContent(flag, id, vipFlags) { + try { + // 调用壳子超级解析 + const playData = { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '芒果TV2', + url: id, + header: JSON.stringify({ + 'User-Agent': this.headers['User-Agent'], + 'Referer': 'https://www.mgtv.com', + 'Origin': 'https://www.mgtv.com' + }) + }; + + return playData; + + } catch (error) { + console.error(`playerContent error: ${error.message}`); + return { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '芒果TV2', + url: id, + header: JSON.stringify(this.headers) + }; + } + } + + localProxy(param) { + return null; + } +} + +export default new Spider(); \ No newline at end of file diff --git "a/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" "b/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" new file mode 100644 index 00000000..ffdb7289 --- /dev/null +++ "b/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" @@ -0,0 +1,356 @@ +/** + * 优酷视频 - 猫影视/TVBox JS爬虫格式 + * 调用壳子超级解析功能(壳子会自动读取json配置) + @header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '优酷视频', + lang: 'cat' + }) + */ + +class Spider extends BaseSpider { + + constructor() { + super(); + this.host = 'https://www.youku.com'; + this.sessionStore = {}; + + this.headers = { + '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', + 'Referer': 'https://www.youku.com', + 'Accept': 'application/json, text/plain, */*', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', + 'Accept-Encoding': 'gzip, deflate, br', + 'Connection': 'keep-alive' + }; + } + + init(extend = '') { + return ''; + } + + getName() { + return '优酷视频'; + } + + isVideoFormat(url) { + return true; + } + + manualVideoCheck() { + return false; + } + + destroy() { + // 清理资源 + } + + homeContent(filter) { + const categories = '电视剧&电影&综艺&动漫&少儿&纪录片&文化&亲子&教育&搞笑&生活&体育&音乐&游戏'.split('&'); + + const result = { + class: categories.map(name => ({ + type_id: name, + type_name: name + })) + }; + + return result; + } + + homeVideoContent() { + return {list: []}; + } + + async categoryContent(tid, pg, filter, extend) { + try { + const page = parseInt(pg) || 1; + let filterObj = {}; + + if (extend && typeof extend === 'object') { + filterObj = extend; + } + + filterObj.type = tid; + const paramsStr = JSON.stringify(filterObj); + + let url = `https://www.youku.com/category/data?optionRefresh=1&pageNo=${page}¶ms=${encodeURIComponent(paramsStr)}`; + + // 处理session + if (page > 1 && this.sessionStore[tid]) { + url = url.replace("optionRefresh=1", `session=${encodeURIComponent(this.sessionStore[tid])}`); + } + + const response = await this.fetch(url, {}, this.headers); + const resData = response.data; + + if (resData.data && resData.data.filterData && resData.data.filterData.session) { + this.sessionStore[tid] = JSON.stringify(resData.data.filterData.session); + } + + const videos = []; + if (resData.data && resData.data.filterData && Array.isArray(resData.data.filterData.listData)) { + const lists = resData.data.filterData.listData; + for (const it of lists) { + let vid = ""; + if (it.videoLink && it.videoLink.includes("id_")) { + vid = it.videoLink.split("id_")[1].split(".html")[0]; + } else { + vid = "msearch:" + it.title; + } + + videos.push({ + vod_id: vid, + vod_name: it.title || '', + vod_pic: it.img || '', + vod_remarks: it.summary || '', + vod_content: it.subTitle || '' + }); + } + } + + return { + list: videos, + page: page, + pagecount: 9999, + limit: 20, + total: 999999 + }; + + } catch (error) { + console.error(`categoryContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + safeFixYoukuInitialData(rawStr) { + if (!rawStr) return '{}'; + let s = rawStr + .replace(/^[\s\S]*?window\.__INITIAL_DATA__\s*[=:]\s*/, '') + .replace(/;[\s\S]*$/, '') + .replace(/\.{3,}[\s\S]*$/, '') + .replace(/,\s*$/, '') + .trim(); + + if (!s || s.length < 2 || !/^\{/.test(s)) { + return '{}'; + } + + let open = 0, close = 0; + for (let char of s) { + if (char === '{') open++; + if (char === '}') close++; + } + + if (open > close) { + s += '}'.repeat(open - close); + } + if (!s.startsWith('{')) { + s = '{' + s; + } + if (!s.endsWith('}')) { + s += '}'; + } + + return s; + } + + getSafe(obj, path, defaultValue = '') { + if (!obj || typeof obj !== 'object') return defaultValue; + try { + return path.split('.').reduce((o, key) => { + if (o == null) return defaultValue; + return o[key]; + }, obj) ?? defaultValue; + } catch { + return defaultValue; + } + } + + async detailContent(ids) { + try { + const id = ids[0]; + + // 获取剧集列表 + const apiUrl = `https://search.youku.com/api/search?appScene=show_episode&showIds=${id}`; + const apiResponse = await this.fetch(apiUrl, {}, this.headers); + const jsonData = apiResponse.data; + const videoLists = jsonData.serisesList || []; + + // 构建播放列表 + const playUrls = []; + if (videoLists.length > 0) { + for (const item of videoLists) { + const title = item.showVideoStage?.replace("期", "集") || + item.displayName || + item.title || + `第${item.index || '?'}集`; + const url = `https://v.youku.com/v_show/id_${item.videoId}.html`; + playUrls.push(`${title}$${url}`); + } + } + + // 获取详情信息 + let detailInfo = { + title: '', + cover: '', + category: '', + remarks: '', + desc: '' + }; + + try { + const detailUrl = `https://v.youku.com/v_show/id_${id}.html`; + const htmlResponse = await this.fetch(detailUrl, { + headers: { + ...this.headers, + 'Referer': 'https://v.youku.com/' + } + }); + const html = htmlResponse.data; + + // 检查是否触发人机验证 + if (html.includes("人机验证") || html.includes("captcha") || html.includes("verify")) { + detailInfo.desc = "触发优酷人机验证,建议在浏览器中访问优酷官网解除限制后再重试"; + } else if (html.includes("window.__INITIAL_DATA__ =")) { + let dataStr = html.split("window.__INITIAL_DATA__ =")[1]?.split(";")?.[0]?.trim() || '{}'; + dataStr = this.safeFixYoukuInitialData(dataStr); + + try { + const detailJson = JSON.parse(dataStr); + const item = this.getSafe(detailJson, 'moduleList.0.components.0.itemList.0', {}); + const extra = this.getSafe(detailJson, 'pageMap.extra', {}); + + detailInfo.title = item.introTitle || extra.showName || videoLists[0]?.title || ''; + detailInfo.cover = item.showImgV || extra.showImgV || extra.showImg || ''; + detailInfo.category = item.showGenre || extra.videoCategory || ''; + detailInfo.remarks = item.introSubTitle || extra.showSubtitle || item.mark?.text || ''; + } catch (parseErr) { + console.error(`JSON解析失败: ${parseErr.message}`); + } + } else { + detailInfo.title = videoLists[0]?.title?.split(" ")[0] || ''; + } + } catch (detailError) { + console.error(`获取详情失败: ${detailError.message}`); + } + + const vod = { + vod_id: id, + vod_name: detailInfo.title || videoLists[0]?.title || '未知标题', + type_name: detailInfo.category || '', + vod_year: '', + vod_remarks: detailInfo.remarks || '', + vod_content: detailInfo.desc || (detailInfo.remarks ? `简介: ${detailInfo.remarks}` : '暂无简介'), + vod_play_from: playUrls.length > 0 ? '优酷视频' : '', + vod_play_url: playUrls.length > 0 ? playUrls.join('#') : '' + }; + + return {list: [vod]}; + + } catch (error) { + console.error(`detailContent error: ${error.message}`); + return {list: []}; + } + } + + async searchContent(key, quick, pg = '1') { + try { + const page = parseInt(pg) || 1; + const url = `https://search.youku.com/api/search?pg=${page}&keyword=${encodeURIComponent(key)}`; + + const response = await this.fetch(url, {}, this.headers); + const data = response.data; + + const videos = []; + + if (data && Array.isArray(data.pageComponentList)) { + for (const item of data.pageComponentList) { + if (item.commonData) { + const common = item.commonData; + let vid = common.showId || ''; + + if (!vid && common.titleDTO && common.titleDTO.displayName) { + vid = `msearch:${common.titleDTO.displayName}`; + } + + videos.push({ + vod_id: vid, + vod_name: common.titleDTO?.displayName || '', + vod_pic: common.posterDTO?.vThumbUrl || '', + vod_remarks: common.stripeBottom || '', + vod_content: common.updateNotice || '' + }); + } + } + } + + return { + list: videos, + page: page, + pagecount: 9999, + limit: 20, + total: 999999 + }; + + } catch (error) { + console.error(`searchContent error: ${error.message}`); + return { + list: [], + page: pg, + pagecount: 0, + limit: 20, + total: 0 + }; + } + } + + async playerContent(flag, id, vipFlags) { + try { + // 关键:调用壳子超级解析 + // 壳子会自动读取json配置中的解析规则 + const playData = { + parse: 1, // 必须为1,表示需要解析 + jx: 1, // 必须为1,启用解析 + play_parse: true, // 启用播放解析 + parse_type: '壳子超级解析', + parse_source: '优酷视频', + url: id, // 原始优酷链接 + header: JSON.stringify({ + 'User-Agent': this.headers['User-Agent'], + 'Referer': 'https://www.youku.com', + 'Origin': 'https://www.youku.com' + }) + }; + + return playData; + + } catch (error) { + console.error(`playerContent error: ${error.message}`); + // 即使出错也返回超级解析参数,让壳子处理 + return { + parse: 1, + jx: 1, + play_parse: true, + parse_type: '壳子超级解析', + parse_source: '优酷视频', + url: id, + header: JSON.stringify(this.headers) + }; + } + } + + localProxy(param) { + return null; + } +} + +export default new Spider(); \ No newline at end of file From a9be6aa0c219931204278116b766a8bcf33f03fe Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 22:57:54 +0800 Subject: [PATCH 49/99] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=8F=A6=E7=B1=BB?= =?UTF-8?q?=E5=86=99=E6=B3=95=E7=9A=84cat=E6=BA=90=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs_drpy/drpyInject.js | 13 ++++++++++++- .../\345\223\251\345\223\251[\345\256\230].js" | 2 +- .../\345\244\256\345\244\256[\345\256\230].js" | 2 +- .../\345\245\207\345\245\207[\345\256\230].js" | 2 +- .../\346\236\234\346\236\234[\345\256\230].js" | 2 +- .../\351\205\267\351\205\267[\345\256\230].js" | 2 +- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libs_drpy/drpyInject.js b/libs_drpy/drpyInject.js index b473ec13..27122610 100644 --- a/libs_drpy/drpyInject.js +++ b/libs_drpy/drpyInject.js @@ -733,11 +733,22 @@ class BaseSpider { this.play = this.playerContent; this.homeVod = this.homeVideoContent; this.proxy = this.localProxy; + // this.fetch = request; } async fetch(url, options) { const content = (await req(url, options)).content; - return {data: content.parseX}; + return { + content, + get data() { // data尝试返回object + try { + // console.log('get data:', this.content); + return this.content.parseX; + } catch (e) { + return {}; + } + } + }; } async homeContent() { diff --git "a/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" "b/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" index df164c9c..91cecaa6 100644 --- "a/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" +++ "b/spider/catvod/\345\223\251\345\223\251[\345\256\230].js" @@ -5,7 +5,7 @@ searchable: 1, filterable: 1, quickSearch: 1, - title: 'B站', + title: '哩哩[官]', lang: 'cat' }) */ diff --git "a/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" "b/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" index 895aea15..478e4b10 100644 --- "a/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" +++ "b/spider/catvod/\345\244\256\345\244\256[\345\256\230].js" @@ -5,7 +5,7 @@ searchable: 1, filterable: 1, quickSearch: 1, - title: '央视大全', + title: '央央[官]', lang: 'cat' }) */ diff --git "a/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" "b/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" index 956ed6b1..89ce8472 100644 --- "a/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" +++ "b/spider/catvod/\345\245\207\345\245\207[\345\256\230].js" @@ -5,7 +5,7 @@ searchable: 1, filterable: 1, quickSearch: 1, - title: '爱奇艺视频', + title: '奇奇[官]', lang: 'cat' }) */ diff --git "a/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" "b/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" index 33f6e159..ea5846fc 100644 --- "a/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" +++ "b/spider/catvod/\346\236\234\346\236\234[\345\256\230].js" @@ -5,7 +5,7 @@ searchable: 1, filterable: 1, quickSearch: 1, - title: '芒果TV', + title: '果果[官]', lang: 'cat' }) */ diff --git "a/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" "b/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" index ffdb7289..754e204f 100644 --- "a/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" +++ "b/spider/catvod/\351\205\267\351\205\267[\345\256\230].js" @@ -5,7 +5,7 @@ searchable: 1, filterable: 1, quickSearch: 1, - title: '优酷视频', + title: '酷酷[官]', lang: 'cat' }) */ From f5b6905c43fa67744347e0ee21966a167d60c42a Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 23:07:11 +0800 Subject: [PATCH 50/99] =?UTF-8?q?add:=20=E5=A2=9E=E5=8A=A0php=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "spider/php/B\347\253\231.php" | 326 +++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 "spider/php/B\347\253\231.php" diff --git "a/spider/php/B\347\253\231.php" "b/spider/php/B\347\253\231.php" new file mode 100644 index 00000000..902093e0 --- /dev/null +++ "b/spider/php/B\347\253\231.php" @@ -0,0 +1,326 @@ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36", + "Referer" => "https://www.bilibili.com" + ]; + + public function __construct() { + $this->extendDict = $this->getExtendDict(); + $this->cookie = $this->getCookie(); + } + + private function getExtendDict() { + return [ + 'cookie' => $this->getConfigCookie(), + 'thread' => '0' + ]; + } + + private function getConfigCookie() { + // 配置您的B站Cookie + return 'buvid3=xxxx; SESSDATA=xxxx;'; + } + + private function getCookie() { + $cookie = $this->extendDict['cookie'] ?? ''; + if (empty($cookie)) return []; + + $cookies = []; + $pairs = explode(';', $cookie); + foreach ($pairs as $pair) { + $pair = trim($pair); + if (strpos($pair, '=') !== false) { + list($name, $value) = explode('=', $pair, 2); + $cookies[trim($name)] = trim($value); + } + } + return $cookies; + } + + private function httpRequest($url, $params = []) { + $ch = curl_init(); + + if (!empty($params)) { + $url .= '?' . http_build_query($params); + } + + $headers = []; + foreach ($this->header as $key => $value) { + $headers[] = $key . ': ' . $value; + } + + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 10, + CURLOPT_HTTPHEADER => $headers, + CURLOPT_COOKIE => $this->buildCookieString(), + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_FOLLOWLOCATION => true + ]); + + $response = curl_exec($ch); + curl_close($ch); + + return json_decode($response, true) ?: []; + } + + private function buildCookieString() { + $pairs = []; + foreach ($this->cookie as $name => $value) { + $pairs[] = $name . '=' . $value; + } + return implode('; ', $pairs); + } + + // homeContent - 首页分类 + public function homeContent() { + $classes = [ + ["type_id" => "沙雕仙逆", "type_name" => "傻屌仙逆"], + ["type_id" => "沙雕动画", "type_name" => "沙雕动画"], + ["type_id" => "纪录片超清", "type_name" => "纪录片"], + ["type_id" => "演唱会超清", "type_name" => "演唱会"], + ["type_id" => "音乐超清", "type_name" => "流行音乐"], + ["type_id" => "美食超清", "type_name" => "美食"], + ["type_id" => "食谱", "type_name" => "食谱"], + ["type_id" => "体育超清", "type_name" => "体育"], + ["type_id" => "球星", "type_name" => "球星"], + ["type_id" => "中小学教育", "type_name" => "教育"], + ["type_id" => "幼儿教育", "type_name" => "幼儿教育"], + ["type_id" => "旅游", "type_name" => "旅游"], + ["type_id" => "风景4K", "type_name" => "风景"], + ["type_id" => "说案", "type_name" => "说案"], + ["type_id" => "知名UP主", "type_name" => "知名UP主"], + ["type_id" => "探索发现超清", "type_name" => "探索发现"], + ["type_id" => "鬼畜", "type_name" => "鬼畜"], + ["type_id" => "搞笑超清", "type_name" => "搞笑"], + ["type_id" => "儿童超清", "type_name" => "儿童"], + ["type_id" => "动物世界超清", "type_name" => "动物世界"], + ["type_id" => "相声小品超清", "type_name" => "相声小品"], + ["type_id" => "戏曲", "type_name" => "戏曲"], + ["type_id" => "解说", "type_name" => "解说"], + ["type_id" => "演讲", "type_name" => "演讲"], + ["type_id" => "小姐姐超清", "type_name" => "小姐姐"], + ["type_id" => "荒野求生超清", "type_name" => "荒野求生"], + ["type_id" => "健身", "type_name" => "健身"], + ["type_id" => "帕梅拉", "type_name" => "帕梅拉"], + ["type_id" => "太极拳", "type_name" => "太极拳"], + ["type_id" => "广场舞", "type_name" => "广场舞"], + ["type_id" => "舞蹈", "type_name" => "舞蹈"], + ["type_id" => "音乐", "type_name" => "音乐"], + ["type_id" => "歌曲", "type_name" => "歌曲"], + ["type_id" => "MV4K", "type_name" => "MV"], + ["type_id" => "舞曲超清", "type_name" => "舞曲"], + ["type_id" => "4K", "type_name" => "4K"], + ["type_id" => "电影", "type_name" => "电影"], + ["type_id" => "电视剧", "type_name" => "电视剧"], + ["type_id" => "白噪音超清", "type_name" => "白噪音"], + ["type_id" => "考公考证", "type_name" => "考公考证"], + ["type_id" => "平面设计教学", "type_name" => "平面设计教学"], + ["type_id" => "软件教程", "type_name" => "软件教程"], + ["type_id" => "Windows", "type_name" => "Windows"] + ]; + + return ['class' => $classes]; + } + + // homeVideoContent - 首页推荐视频 + public function homeVideoContent() { + $url = 'https://api.bilibili.com/x/web-interface/popular'; + $data = $this->httpRequest($url, ['ps' => 20, 'pn' => 1]); + + $videos = []; + if (isset($data['data']['list'])) { + foreach ($data['data']['list'] as $item) { + $videos[] = [ + 'vod_id' => $item['aid'], + 'vod_name' => strip_tags($item['title']), + 'vod_pic' => $item['pic'], + 'vod_remarks' => $this->formatDuration($item['duration']) + ]; + } + } + + return ['list' => $videos]; + } + + // categoryContent - 分类内容(使用搜索API) + public function categoryContent($tid, $page, $filters = []) { + $page = max(1, intval($page)); + + $url = 'https://api.bilibili.com/x/web-interface/search/type'; + $params = [ + 'search_type' => 'video', + 'keyword' => $tid, + 'page' => $page + ]; + + $data = $this->httpRequest($url, $params); + + $videos = []; + if (isset($data['data']['result'])) { + foreach ($data['data']['result'] as $item) { + if ($item['type'] !== 'video') continue; + + $videos[] = [ + 'vod_id' => $item['aid'], + 'vod_name' => strip_tags($item['title']), + 'vod_pic' => 'https:' . $item['pic'], + 'vod_remarks' => $this->formatSearchDuration($item['duration']) + ]; + } + } + + $pageCount = $data['data']['numPages'] ?? 1; + $total = $data['data']['numResults'] ?? count($videos); + + return [ + 'list' => $videos, + 'page' => $page, + 'pagecount' => $pageCount, + 'limit' => 20, + 'total' => $total + ]; + } + + // detailContent - 视频详情 + public function detailContent($vid) { + $url = 'https://api.bilibili.com/x/web-interface/view'; + $data = $this->httpRequest($url, ['aid' => $vid]); + + if (!isset($data['data'])) { + return ['list' => []]; + } + + $video = $data['data']; + + // 构建播放列表 + $playUrl = ''; + foreach ($video['pages'] as $index => $page) { + $part = $page['part'] ?: '第' . ($index + 1) . '集'; + $duration = $this->formatDuration($page['duration']); + $playUrl .= "{$part}\${$vid}_{$page['cid']}#"; + } + + $vod = [ + "vod_id" => $vid, + "vod_name" => strip_tags($video['title']), + "vod_pic" => $video['pic'], + "vod_content" => $video['desc'], + "vod_play_from" => "B站视频", + "vod_play_url" => rtrim($playUrl, '#') + ]; + + return ['list' => [$vod]]; + } + + // playContent - 播放地址(高清优化) + public function playContent($vid) { + if (strpos($vid, '_') !== false) { + list($avid, $cid) = explode('_', $vid); + } else { + return $this->errorResponse('无效的视频ID格式'); + } + + // 使用高质量参数 + $url = 'https://api.bilibili.com/x/player/playurl'; + $params = [ + 'avid' => $avid, + 'cid' => $cid, + 'qn' => 112, // 原画质量 + 'fnval' => 0, + ]; + + $data = $this->httpRequest($url, $params); + + if (!isset($data['data']) || $data['code'] !== 0) { + return $this->errorResponse('获取播放地址失败'); + } + + // 直接返回第一个播放地址 + if (isset($data['data']['durl'][0]['url'])) { + $playUrl = $data['data']['durl'][0]['url']; + + $headers = $this->header; + $headers['Referer'] = 'https://www.bilibili.com/video/av' . $avid; + $headers['Origin'] = 'https://www.bilibili.com'; + + return [ + 'parse' => 0, + 'url' => $playUrl, + 'header' => $headers, + 'danmaku' => "https://api.bilibili.com/x/v1/dm/list.so?oid={$cid}" + ]; + } + + return $this->errorResponse('无法获取播放地址'); + } + + // 工具函数 + private function formatDuration($seconds) { + if ($seconds <= 0) return '00:00'; + $minutes = floor($seconds / 60); + $secs = $seconds % 60; + return sprintf('%02d:%02d', $minutes, $secs); + } + + private function formatSearchDuration($duration) { + $parts = explode(':', $duration); + if (count($parts) === 2) { + return $duration; + } + return '00:00'; + } + + private function errorResponse($message) { + return [ + 'parse' => 0, + 'url' => '', + 'error' => $message + ]; + } +} + +// 主处理逻辑 +$ac = $_GET['ac'] ?? 'detail'; +$t = $_GET['t'] ?? ''; +$pg = $_GET['pg'] ?? '1'; +$f = $_GET['f'] ?? ''; +$ids = $_GET['ids'] ?? ''; +$id = $_GET['id'] ?? ''; + +$spider = new BiliBiliSpider(); + +try { + switch ($ac) { + case 'detail': + if (!empty($ids)) { + echo json_encode($spider->detailContent($ids)); + } elseif (!empty($t)) { + $filters = !empty($f) ? json_decode($f, true) : []; + echo json_encode($spider->categoryContent($t, $pg, $filters)); + } else { + $result = $spider->homeContent(); + $videoResult = $spider->homeVideoContent(); + $result['list'] = $videoResult['list']; + echo json_encode($result); + } + break; + + case 'play': + echo json_encode($spider->playContent($id)); + break; + + default: + echo json_encode(['error' => '未知操作: ' . $ac]); + } +} catch (Exception $e) { + echo json_encode(['error' => $e->getMessage()]); +} +?> From bcd8939bfba1b44dee3299713e155d415e8bfe1e Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 23:32:16 +0800 Subject: [PATCH 51/99] =?UTF-8?q?add:=20=E5=A2=9E=E5=8A=A0php=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spider/php/config.php | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 spider/php/config.php diff --git a/spider/php/config.php b/spider/php/config.php new file mode 100644 index 00000000..d8327c65 --- /dev/null +++ b/spider/php/config.php @@ -0,0 +1,46 @@ + "php_" . $filename, + "name" => $filename . "(PHP)", + "type" => 4, + "api" => "http://127.0.0.1:9980/" . $filename . ".php", + "searchable" => 1, + "quickSearch" => 1, + "changeable" => 0 + ]; +} + +// 输出 JSON +echo json_encode( + ["sites" => $sites], + JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT +); From 6d69335db1cec97a306827a889452c49a1238c88 Mon Sep 17 00:00:00 2001 From: Taois Date: Tue, 20 Jan 2026 23:41:27 +0800 Subject: [PATCH 52/99] =?UTF-8?q?add:=20=E5=A2=9E=E5=8A=A0php=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spider/php/config.php | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/spider/php/config.php b/spider/php/config.php index d8327c65..052cfc2a 100644 --- a/spider/php/config.php +++ b/spider/php/config.php @@ -1,31 +1,24 @@ $sites], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT From d39a76e6f936c013ed2330145080408b3fbaa996 Mon Sep 17 00:00:00 2001 From: Taois Date: Wed, 21 Jan 2026 10:12:51 +0800 Subject: [PATCH 53/99] =?UTF-8?q?docs:=E5=A2=9E=E5=8A=A0=E8=B6=85=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + public/index.html | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 3cbdcc29..f8488af2 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ nodejs作为服务端的drpy实现。全面升级异步写法 * [猫源调试教程](/docs/catDebug.md) * [接口压测教程](/docs/httpTest.md) * [AI编程工具 trae](https://www.trae.ai/account-setting#subscription) | 邮编ZIP输入: 518000 +* [推荐使用AI模型-GLM4.7](https://www.bigmodel.cn/glm-coding?ic=DRV3C8M5NX) | [GLM配置文档](https://docs.bigmodel.cn/cn/coding-plan/tool/trae) * [免费AI-360纳米](https://bot.n.cn/)|[免费AI-当贝AI](https://ai.dangbei.com/chat)|[国外聚合全模型](https://lmarena.ai/) * [本站防止爬虫协议](/robots.txt) * [油猴脚本-反切屏检测](/public/monkey/check_screen_leave.user.js) diff --git a/public/index.html b/public/index.html index 83d6552e..41ed026e 100644 --- a/public/index.html +++ b/public/index.html @@ -25,6 +25,7 @@

    常用超链接

  • 猫源调试教程
  • 接口压测教程
  • AI编程工具 trae | 邮编ZIP输入: 518000
  • +
  • 推荐使用AI模型-GLM4.7 | GLM配置文档
  • 免费AI-360纳米|免费AI-当贝AI|国外聚合全模型
  • 本站防止爬虫协议
  • 油猴脚本-反切屏检测
  • From 6e6d6041fe3c6a8f6e4d9417ae6d90be05e97827 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 21 Jan 2026 14:44:28 +0800 Subject: [PATCH 54/99] =?UTF-8?q?Update=20=E6=A2=A8=E5=9B=AD=E8=A1=8C[?= =?UTF-8?q?=E6=88=8F].js=20and=20add=20new=20js=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\346\234\250\345\205\256[\344\274\230].js" | 14 +- ...\345\233\255\350\241\214[\346\210\217].js" | 261 ++++++++++++++++++ ...\351\237\263\344\271\220[\345\220\254].js" | 14 + ...\351\237\263\344\271\220[\345\220\254].js" | 49 +--- 4 files changed, 289 insertions(+), 49 deletions(-) rename "spider/js_bad/\346\234\250\345\205\256[\344\274\230].js" => "spider/js/\346\234\250\345\205\256[\344\274\230].js" (88%) create mode 100644 "spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" create mode 100644 "spider/js/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].js" diff --git "a/spider/js_bad/\346\234\250\345\205\256[\344\274\230].js" "b/spider/js/\346\234\250\345\205\256[\344\274\230].js" similarity index 88% rename from "spider/js_bad/\346\234\250\345\205\256[\344\274\230].js" rename to "spider/js/\346\234\250\345\205\256[\344\274\230].js" index 918c35da..59cac191 100644 --- "a/spider/js_bad/\346\234\250\345\205\256[\344\274\230].js" +++ "b/spider/js/\346\234\250\345\205\256[\344\274\230].js" @@ -20,7 +20,19 @@ var rule = { quickSearch: 1, filterable: 0, headers: { - 'User-Agent': MOBILE_UA + 'User-Agent': MOBILE_UA, + 'Accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'x-platform': 'web' }, play_parse: true, search_match: true, diff --git "a/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" "b/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" new file mode 100644 index 00000000..22af9d45 --- /dev/null +++ "b/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" @@ -0,0 +1,261 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 0, + title: '梨园行戏曲', + author: 'EylinSir', + '类型': '影视', + logo: 'https://img.znds.com//uploads/new/221222/9-2212221050561N.png', + lang: 'ds' +}) +*/ + +var rule = { + 类型: '影视', + author: 'EylinSir', + title: '梨园行戏曲', + desc: '梨园行戏曲源', + host: 'https://fly.daoran.tv', + homeUrl: 'https://fly.daoran.tv', + url: '/API_ROP/search/album/screen', + searchUrl: '/API_ROP/search/album/list?keyword=**', + logo: 'https://img.znds.com//uploads/new/221222/9-2212221050561N.png', + searchable: 1, + quickSearch: 0, + filterable: 1, + timeout: 10000, + play_parse: true, + headers: { + 'md5': 'SkvyrWqK9QHTdCT12Rhxunjx+WwMTe9y4KwgeASFDhbYabRSPskR0Q==', + 'Content-Type': 'application/json; charset=UTF-8', + 'User-Agent': 'okhttp/3.12.10', + 'Host': 'fly.daoran.tv', + 'Connection': 'Keep-Alive' + }, + + request: async function (url, obj) { + obj = obj || {}; + let response = await _fetch(url, { + method: obj.method || 'POST', + headers: obj.headers || this.headers, + body: obj.data ? JSON.stringify(obj.data) : undefined + }); + return response.text(); + }, + + _format_img: function (img) { + if (!img) { + return ''; + } + if (!img.startsWith('http')) { + return `https://ottphoto.daoran.tv/HD/${img}`; + } + return img; + }, + + 预处理: async function () {}, + + class_parse: async function () { + let cate_list = [ + {"n": "全部", "v": ""}, + {"n": "黄梅戏", "v": "hmx"}, {"n": "京剧", "v": "jingju"}, {"n": "曲剧", "v": "quju"}, + {"n": "秦腔", "v": "qinq"}, {"n": "潮剧", "v": "chaoju"}, {"n": "沪剧", "v": "huju"}, + {"n": "昆曲", "v": "kunqu"}, {"n": "淮剧", "v": "huaiju"}, {"n": "婺剧", "v": "wuju"}, + {"n": "河南大鼓书", "v": "hndgs"}, {"n": "滇剧", "v": "dianju"}, {"n": "老年大学", "v": "WK"}, + {"n": "绍剧", "v": "shaojv"}, {"n": "曲艺晚会", "v": "else"}, {"n": "皮影戏", "v": "pyx"}, + {"n": "四平调", "v": "spd"}, {"n": "吕剧", "v": "lvjv"}, {"n": "柳琴戏", "v": "liuqx"}, + {"n": "莆仙戏", "v": "pxx"}, {"n": "宛梆", "v": "wb"}, {"n": "锡剧", "v": "xiju"}, + {"n": "大平调", "v": "dpd"}, {"n": "话剧", "v": "huaju"}, {"n": "西秦戏", "v": "xqx"}, + {"n": "川剧", "v": "chuanju"}, {"n": "赣剧", "v": "tagId"}, {"n": "太康道情", "v": "tkdq"}, + {"n": "闽剧", "v": "minju"}, {"n": "梅花大鼓", "v": "mhdg"}, {"n": "吉剧", "v": "jiju"}, + {"n": "白字戏", "v": "bzx"}, {"n": "豫剧", "v": "yuju"}, {"n": "越剧", "v": "yueju"}, + {"n": "评剧", "v": "pingju"}, {"n": "坠子", "v": "hnzz"}, {"n": "河北梆子", "v": "hbbz"}, + {"n": "粤剧", "v": "gddx"}, {"n": "二夹弦", "v": "ejx"}, {"n": "河南琴书", "v": "hnqs"}, + {"n": "戏曲", "v": "xq"}, {"n": "二人台", "v": "ERT"}, {"n": "越调", "v": "yued"}, + {"n": "乐腔", "v": "lq"}, {"n": "扬剧", "v": "yangju"}, {"n": "京韵大鼓", "v": "jydg"}, + {"n": "彩调", "v": "caidiao"}, {"n": "琼剧", "v": "qiongju"}, {"n": "蒲剧", "v": "pujv"}, + {"n": "西河大鼓", "v": "xhdg"}, {"n": "湘剧", "v": "xj"}, {"n": "麦田乡韾", "v": "mtxy"}, + {"n": "评书", "v": "pingshu"}, {"n": "庐剧", "v": "luju"}, {"n": "单弦", "v": "danxian"}, + {"n": "花鼓戏", "v": "huagx"}, {"n": "相声", "v": "xiang"}, {"n": "四股弦", "v": "sgx"}, + {"n": "保定老调", "v": "bdld"}, {"n": "晋剧", "v": "jinju"}, {"n": "其他", "v": "other"}, + {"n": "正字戏", "v": "zzx"}, {"n": "楚剧", "v": "chuju"} + ]; + + return { + class: [{ 'type_name': '戏曲片库', 'type_id': 'all' }], + filters: { + "all": [ + {"key": "sect", "name": "曲种", "value": cate_list}, + {"key": "area", "name": "资费", "value": [{"n": "全部", "v": "0"}, {"n": "免费", "v": "1"}, {"n": "VIP", "v": "2"}]}, + {"key": "sort", "name": "排序", "value": [{"n": "最热", "v": "hot"}, {"n": "最新", "v": "online"}]} + ] + } + }; + }, + + 推荐: async function () { + return await this.一级('all', 1, {}, {}); + }, + + 一级: async function (tid, pg, filter, extend) { + let url = `${this.host}/API_ROP/search/album/screen`; + let sect = extend?.sect || ''; + if (tid === 'all' && !sect) { + sect = ''; + } + + let payload = { + "cur": parseInt(pg), + "pageSize": 30, + "resType": 1, + "sect": sect, + "orderby": extend?.sort || 'hot', + "tagId": 0, + "userId": "92315ec6e58a45ba7f47fd143b3d7956", + "channel": "vivo", + "item": "y9", + "nodeCode": "001000", + "project": "lyhxcx" + }; + + let area = extend?.area || '0'; + if (area === '1' || area === '2') { + payload['free'] = parseInt(area); + } + + try { + let resp = await this.request(url, { data: payload }); + let json = JSON.parse(resp); + let data = json.pb || json.data || {}; + let vod_list = []; + for (let item of data.dataList || []) { + vod_list.push({ + title: item.name, + url: `${this.host}/API_ROP/album/res/list?albumCode=${item.code}`, + desc: (item.publishTime || '').split(' ')[0], + pic_url: this._format_img(item.imgsec), + vod_year: (item.publishTime || '').substring(0, 4) + }); + } + + return setResult(vod_list); + } catch (e) { + console.error(e); + return setResult([]); + } + }, + + 二级: async function () { + let albumCode = this.input.match(/albumCode=(.*?)(?:&|$)/)[1]; + let url = `${this.host}/API_ROP/album/res/list`; + + let payload = { + "albumCode": albumCode, + "cur": 1, + "pageSize": 500, + "userId": "92315ec6e58a45ba7f47fd143b3d7956", + "channel": "vivo", + "item": "y9", + "nodeCode": "001000", + "project": "lyhxcx" + }; + + try { + let resp = await this.request(url, { data: payload }); + let json = JSON.parse(resp); + let album = json.album || {}; + let tracks = json.pb?.dataList || []; + tracks.sort((a, b) => parseInt(a.sort || 0) - parseInt(b.sort || 0)); + let play_urls = []; + for (let t of tracks) { + if (t.code) { + play_urls.push(`${t.name.replace(/\$/g, '_')}$${t.code}`); + } + } + + let VOD = { + vod_id: albumCode, + vod_name: album.name || '未知', + vod_pic: this._format_img(album.imgsec), + type_name: "戏曲", + vod_year: album.publishTime || '', + vod_area: "中国", + vod_content: album.des || '暂无简介', + vod_play_from: "梨园行", + vod_play_url: play_urls.join('#') + }; + + return VOD; + } catch (e) { + console.error(e); + return {}; + } + }, + + 搜索: async function () { + let url = `${this.host}/API_ROP/search/album/list`; + let payload = { + "cur": parseInt(this.MY_PAGE), + "pageSize": 20, + "keyword": this.KEY, + "item": "y9", + "nodeCode": "001000", + "orderby": "hot", + "px": 2, + "sect": [], + "userId": "92315ec6e58a45ba7f47fd143b3d7956", + "project": "lyhxcx" + }; + + try { + let resp = await this.request(url, { data: payload }); + let json = JSON.parse(resp); + let data = json.pb || json.data || {}; + let vod_list = []; + for (let item of data.dataList || []) { + vod_list.push({ + title: item.name, + url: `${this.host}/API_ROP/album/res/list?albumCode=${item.code}`, + desc: (item.publishTime || ''), + pic_url: this._format_img(item.imgsec) + }); + } + return setResult(vod_list); + } catch (e) { + console.error(e); + return setResult([]); + } + }, + + lazy: async function () { + let resCode = this.input; + let url = `${this.host}/API_ROP/play/get/playurl`; + let payload = { + "resCode": resCode, + "item": "y9", + "mask": 0, + "nodeCode": "001000", + "project": "lyhxcx", + "px": 2, + "userId": "92315ec6e58a45ba7f47fd143b3d7956" + }; + + try { + let resp = await this.request(url, { data: payload }); + let json = JSON.parse(resp); + let play_url = json.playres?.playurl || ''; + return { + parse: 0, + url: play_url, + header: { 'User-Agent': this.headers['User-Agent'] } + }; + } catch (e) { + console.error(e); + return { + parse: 0, + url: '' + }; + } + } +}; \ No newline at end of file diff --git "a/spider/js/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].js" new file mode 100644 index 00000000..28c15f7c --- /dev/null +++ "b/spider/js/\347\210\261\347\216\251\351\237\263\344\271\220[\345\220\254].js" @@ -0,0 +1,14 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '爱玩音乐', + author: 'EylinSir', + '类型': '音乐', + logo: 'https://www.22a5.com/favicon.ico', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICfpn7PkuZAnLAogICAgdGl0bGU6ICfniLHnjqnpn7PkuZAnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgaG9zdDogJ2h0dHBzOi8vd3d3LjIyYTUuY29tJywKICAgIHVybDogJy9meWNsYXNzL2Z5ZmlsdGVyLWZ5cGFnZS8nLAogICAgbG9nbzogJ2h0dHBzOi8vd3d3LjIyYTUuY29tL2Zhdmljb24uaWNvJywKICAgIGNsYXNzX25hbWU6ICfnlLXlj7Am5q2M5Y2VJuS4k+i+kSbmrYzmiYsm6auY5riFTVYm5paw5q2M5qacJlRPUOamnOWNlScsCiAgICBjbGFzc191cmw6ICcvcmFkaW9saXN0L2luZGV4Lmh0bWwmL3BsYXl0eXBlL2luZGV4Lmh0bWwmL2FsYnVtbGlzdC9pbmRleC5odG1sJi9zaW5nZXJsaXN0L2luZGV4L2luZGV4L2luZGV4L2luZGV4Lmh0bWwmL212bGlzdC9odWF5dS5odG1sJi9saXN0L25ldy5odG1sJi9saXN0L3RvcC5odG1sJywKICAgIHNlYXJjaFVybDogJy9zby8qKi9meXBhZ2UuaHRtbCcsCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDEsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgdGltZW91dDogNTAwMCwKICAgIHBsYXlfcGFyc2U6IHRydWUsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgJ1VzZXItQWdlbnQnOiBNT0JJTEVfVUEsCiAgICAgICAgJ1JlZmVyZXInOiAnaHR0cHM6Ly93d3cuMjJhNS5jb20vJwogICAgfSwKICAgIGZpbHRlcjogewogICAgICAgICIvcmFkaW9saXN0L2luZGV4Lmh0bWwiOiBbeyBrZXk6ICJpZCIsIG5hbWU6ICLliIbnsbsiLCB2YWx1ZTogW3sgIm4iOiAi5pyA5pawIiwgInYiOiAiaW5kZXgiIH0sIHsgIm4iOiAi5pyA54OtIiwgInYiOiAiaG90IiB9LCB7ICJuIjogIuacieWjsOWwj+ivtCIsICJ2IjogIm5vdmVsIiB9LCB7ICJuIjogIuebuOWjsCIsICJ2IjogInhpYW5neWkiIH0sIHsgIm4iOiAi6Z+z5LmQIiwgInYiOiAibXVzaWMiIH0sIHsgIm4iOiAi5oOF5oSfIiwgInYiOiAiZW1vdGlvbiIgfSwgeyAibiI6ICLlm73mvKsiLCAidiI6ICJnYW1lIiB9LCB7ICJuIjogIuW9seinhiIsICJ2IjogInlpbmdzaGkiIH0sIHsgIm4iOiAi6ISx5Y+j56eAIiwgInYiOiAidGFsa3Nob3ciIH0sIHsgIm4iOiAi5Y6G5Y+yIiwgInYiOiAiaGlzdG9yeSIgfSwgeyAibiI6ICLlhL/nq6UiLCAidiI6ICJjaGlsZHJlbiIgfSwgeyAibiI6ICLmlZnogrIiLCAidiI6ICJlZHVjYXRpb24iIH0sIHsgIm4iOiAi5YWr5Y2mIiwgInYiOiAiZ29zc2lwIiB9LCB7ICJuIjogIuaOqOeQhiIsICJ2IjogInR1aWxpIiB9LCB7ICJuIjogIuWktOadoSIsICJ2IjogImhlYWRsaW5lIiB9XSB9XSwKICAgICAgICAiL3Npbmdlcmxpc3QvaW5kZXgvaW5kZXgvaW5kZXgvaW5kZXguaHRtbCI6IFsKICAgICAgICAgICAgeyAia2V5IjogImFyZWEiLCAibmFtZSI6ICLlnLDljLoiLCAidmFsdWUiOiBbeyAibiI6ICLlhajpg6giLCAidiI6ICJpbmRleCIgfSwgeyAibiI6ICLljY7or60iLCAidiI6ICJodWF5dSIgfSwgeyAibiI6ICLmrKfnvo4iLCAidiI6ICJvdW1laSIgfSwgeyAibiI6ICLpn6nlm70iLCAidiI6ICJoYW5ndW8iIH0sIHsgIm4iOiAi5pel5pysIiwgInYiOiAicmlicm4iIH1dIH0sCiAgICAgICAgICAgIHsgImtleSI6ICJzZXgiLCAibmFtZSI6ICLmgKfliKsiLCAidmFsdWUiOiBbeyAibiI6ICLlhajpg6giLCAidiI6ICJpbmRleCIgfSwgeyAibiI6ICLnlLciLCAidiI6ICJtYWxlIiB9LCB7ICJuIjogIuWlsyIsICJ2IjogImdpcmwiIH0sIHsgIm4iOiAi57uE5ZCIIiwgInYiOiAiYmFuZCIgfV0gfSwKICAgICAgICAgICAgeyAia2V5IjogImdlbnJlIiwgIm5hbWUiOiAi5rWB5rS+IiwgInZhbHVlIjogW3sgIm4iOiAi5YWo6YOoIiwgInYiOiAiaW5kZXgiIH0sIHsgIm4iOiAi5rWB6KGMIiwgInYiOiAibGl1eGluZyIgfSwgeyAibiI6ICLnlLXlrZAiLCAidiI6ICJkaWFuemkiIH0sIHsgIm4iOiAi5pGH5ruaIiwgInYiOiAieWFvZ3VuIiB9LCB7ICJuIjogIuWYu+WTiCIsICJ2IjogInhpaGEiIH0sIHsgIm4iOiAiUiZCIiwgInYiOiAicmIiIH0sIHsgIm4iOiAi5rCR6LCjIiwgInYiOiAibWlueWFvIiB9LCB7ICJuIjogIueIteWjqyIsICJ2IjogImp1ZXNoaSIgfSwgeyAibiI6ICLlj6TlhbgiLCAidiI6ICJndWRpYW4iIH1dIH0sCiAgICAgICAgICAgIHsgImtleSI6ICJjaGFyIiwgIm5hbWUiOiAi5a2X5q+NIiwgInZhbHVlIjogW3sgIm4iOiAi5YWo6YOoIiwgInYiOiAiaW5kZXgiIH0sIHsgIm4iOiAiQSIsICJ2IjogImEiIH0sIHsgIm4iOiAiQiIsICJ2IjogImIiIH0sIHsgIm4iOiAiQyIsICJ2IjogImMiIH0sIHsgIm4iOiAiRCIsICJ2IjogImQiIH0sIHsgIm4iOiAiRSIsICJ2IjogImUiIH0sIHsgIm4iOiAiRiIsICJ2IjogImYiIH0sIHsgIm4iOiAiRyIsICJ2IjogImciIH0sIHsgIm4iOiAiSCIsICJ2IjogImgiIH0sIHsgIm4iOiAiSSIsICJ2IjogImkiIH0sIHsgIm4iOiAiSiIsICJ2IjogImoiIH0sIHsgIm4iOiAiSyIsICJ2IjogImsiIH0sIHsgIm4iOiAiTCIsICJ2IjogImwiIH0sIHsgIm4iOiAiTSIsICJ2IjogIm0iIH0sIHsgIm4iOiAiTiIsICJ2IjogIm4iIH0sIHsgIm4iOiAiTyIsICJ2IjogIm8iIH0sIHsgIm4iOiAiUCIsICJ2IjogInAiIH0sIHsgIm4iOiAiUSIsICJ2IjogInEiIH0sIHsgIm4iOiAiUiIsICJ2IjogInIiIH0sIHsgIm4iOiAiUyIsICJ2IjogInMiIH0sIHsgIm4iOiAiVCIsICJ2IjogInQiIH0sIHsgIm4iOiAiVSIsICJ2IjogInUiIH0sIHsgIm4iOiAiViIsICJ2IjogInYiIH0sIHsgIm4iOiAiVyIsICJ2IjogInciIH0sIHsgIm4iOiAiWCIsICJ2IjogIngiIH0sIHsgIm4iOiAiWSIsICJ2IjogInkiIH0sIHsgIm4iOiAiWiIsICJ2IjogInoiIH1dIH0KICAgICAgICBdLAogICAgICAgICIvbXZsaXN0L2h1YXl1Lmh0bWwiOiBbeyAia2V5IjogImlkIiwgIm5hbWUiOiAi57G75Z6LIiwgInZhbHVlIjogW3sgIm4iOiAi5Y2O6K+t57K+6YCJIiwgInYiOiAiaHVheXUiIH0sIHsgIm4iOiAi5pel6Z+p57K+6YCJIiwgInYiOiAiIHJpaGFuIiB9LCB7ICJuIjogIuasp+e+jueyvumAiSIsICJ2IjogIm91bWVpIiB9XSB9XQogICAgfSwKCiAgICBfYWJzOiAodXJsKSA9PiB7CiAgICAgICAgaWYgKCF1cmwgfHwgdHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHJldHVybiAnJzsKICAgICAgICByZXR1cm4gdXJsLnN0YXJ0c1dpdGgoJ2h0dHAnKSA/IHVybCA6IGBodHRwczovL3d3dy4yMmE1LmNvbSR7dXJsLnN0YXJ0c1dpdGgoJy8nKSA/IHVybCA6ICcvJyArIHVybH1gOwogICAgfSwKCiAgICBfY2xlYW46ICh0ZXh0KSA9PiAodGV4dCB8fCAnJykucmVwbGFjZSgvKOeIseeOqemfs+S5kOe9kXzop4bpopHkuIvovb3or7TmmI586KeG6aKR5LiL6L295Zyw5Z2AfHd3d1wuMnQ1OFwuY29tfE1QM+WFjei0ueS4i+i9vXxMUkPmrYzor43kuIvovb185YWo6YOo5q2M5puyfFxb56ysXGQr6aG1XF185Yi35pawfOavj+aXpeaOqOiNkHzmnIDmlrB854Ot6ZeofOaOqOiNkHxNVnzpq5jmuIV85peg5o2fKS9naSwgJycpLnRyaW0oKSwKCiAgICBfZ2V0X2l0ZW1zOiBmdW5jdGlvbihodG1sLCBwZGZhLCBwZCwgcGRmaCkgewogICAgICAgIGlmICh0eXBlb2YgaHRtbCAhPT0gJ3N0cmluZycpIHJldHVybiBbXTsKICAgICAgICBjb25zdCBzZWxlY3RvcnMgPSBbJy52aWRlb19saXN0IGxpJywgJy5wbGF5X2xpc3QgbGknLCAnLnBpY19saXN0IGxpJywgJy5zaW5nZXJfbGlzdCBsaScsICcuYWxpIGxpJywgJy5sYXl1aS1yb3cgbGknLCAnLmJhc2VfbCBsaScsICcubGlzdCBsaScsICcuaXRlbSBsaSddOwogICAgICAgIGxldCBpdGVtcyA9IFtdOwogICAgICAgIGZvciAobGV0IHNlbCBvZiBzZWxlY3RvcnMpIHsKICAgICAgICAgICAgbGV0IGxpc3QgPSBwZGZhKGh0bWwsIHNlbCkgfHwgW107CiAgICAgICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkgY29udGludWU7CiAgICAgICAgICAgIGZvciAobGV0IGl0IG9mIGxpc3QpIHsKICAgICAgICAgICAgICAgIGxldCBocmVmID0gcGQoaXQsICdhJiZocmVmJyk7CiAgICAgICAgICAgICAgICBpZiAoIWhyZWYgfHwgaHJlZiA9PT0gJy8nIHx8IC8oXC91c2VyXC98XC9sb2dpblwvfGphdmFzY3JpcHQpLy50ZXN0KGhyZWYpKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGxldCB0aXRsZSA9IHRoaXMuX2NsZWFuKHBkZmgoaXQsICcubmFtZSYmVGV4dCcpIHx8IHBkKGl0LCAnYSYmdGl0bGUnKSB8fCBwZChpdCwgJ2EmJlRleHQnKSk7CiAgICAgICAgICAgICAgICBpZiAoIXRpdGxlKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGxldCBpbWdfc3JjID0gcGQoaXQsICdpbWcmJmRhdGEtb3JpZ2luYWwnKSB8fCBwZChpdCwgJ2ltZyYmZGF0YS1zcmMnKSB8fCBwZChpdCwgJ2ltZyYmc3JjJyk7CiAgICAgICAgICAgICAgICBsZXQgcGljX3VybCA9IHRoaXMuX2FicygoaW1nX3NyYyB8fCAnJykucmVwbGFjZSgnMTIwJywgJzUwMCcpKTsKICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goewogICAgICAgICAgICAgICAgICAgIHRpdGxlOiB0aXRsZSwKICAgICAgICAgICAgICAgICAgICB1cmw6IHRoaXMuX2FicyhocmVmKSwKICAgICAgICAgICAgICAgICAgICBwaWNfdXJsOiBwaWNfdXJsLAogICAgICAgICAgICAgICAgICAgIGRlc2M6ICcnCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaXRlbXM7CiAgICB9LAoKICAgIOaOqOiNkDogYXN5bmMgZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIFtdOwogICAgfSwKCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uKHRpZCwgcGcsIGZpbHRlciwgZXh0ZW5kKSB7CiAgICAgICAgbGV0IHBhZ2UgPSBwZyB8fCAxOwogICAgICAgIGxldCB1cmwgPSB0aWQucmVwbGFjZSgvXC9cLy9nLCAnLycpLnJlcGxhY2UoJy9meWZpbHRlci0xLycsICcnKTsKICAgICAgICBpZiAoL1wvc2luZ2VybGlzdFwvLy50ZXN0KHRpZCkpIHsKICAgICAgICAgICAgbGV0IHAgPSB0aWQuc3BsaXQoJy8nKTsKICAgICAgICAgICAgaWYgKHAubGVuZ3RoID49IDIpIHsKICAgICAgICAgICAgICAgIGxldCBhcmVhID0gZXh0ZW5kLmFyZWEgfHwgcFsyXSB8fCAnaW5kZXgnOwogICAgICAgICAgICAgICAgbGV0IHNleCA9IGV4dGVuZC5zZXggfHwgcFszXSB8fCAnaW5kZXgnOwogICAgICAgICAgICAgICAgbGV0IGdlbnJlID0gZXh0ZW5kLmdlbnJlIHx8IHBbNF0gfHwgJ2luZGV4JzsKICAgICAgICAgICAgICAgIGxldCBjaGFyID0gZXh0ZW5kLmNoYXIgfHwgJ2luZGV4JzsKICAgICAgICAgICAgICAgIHVybCA9IGAvJHtwWzFdfS8ke2FyZWF9LyR7c2V4fS8ke2dlbnJlfS8ke2NoYXJ9Lmh0bWxgOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoZXh0ZW5kLmlkICYmICFbJ2luZGV4JywgJ3RvcCddLmluY2x1ZGVzKGV4dGVuZC5pZCkpIHsKICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoLyhcdyspXC5odG1sJC8sIGV4dGVuZC5pZCArICcuaHRtbCcpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBhZ2UgPiAxKSB7CiAgICAgICAgICAgIGxldCBzZXAgPSAvKFwvc2luZ2VybGlzdFwvfFwvcmFkaW9saXN0XC98XC9tdmxpc3RcL3xcL3BsYXl0eXBlXC98XC9saXN0XC8pLy50ZXN0KHVybCkgPyAnLycgOiAnXyc7CiAgICAgICAgICAgIHVybCA9IHVybC5yZXBsYWNlKC8oX1xkK3xcL1xkKyk/XC5odG1sJC8sIGAke3NlcH0ke3BhZ2V9Lmh0bWxgKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbGV0IGZpbmFsVXJsID0gdGhpcy5fYWJzKHVybCk7CiAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgcmVxKGZpbmFsVXJsKTsKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHRoaXMuX2dldF9pdGVtcyhyZXNwb25zZS5jb250ZW50IHx8IHJlc3BvbnNlLCB0aGlzLnBkZmEsIHRoaXMucGQsIHRoaXMucGRmaCkpOwogICAgfSwKCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uKHdkLCBxdWljaywgcGcpIHsKICAgICAgICBsZXQgcGFnZSA9IHBnIHx8IDE7CiAgICAgICAgbGV0IHVybCA9IHRoaXMuX2FicyhgL3NvLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHdkKX0vJHtwYWdlfS5odG1sYCk7CiAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgcmVxKHVybCk7CiAgICAgICAgcmV0dXJuIHNldFJlc3VsdCh0aGlzLl9nZXRfaXRlbXMocmVzcG9uc2UuY29udGVudCB8fCByZXNwb25zZSwgdGhpcy5wZGZhLCB0aGlzLnBkLCB0aGlzLnBkZmgpKTsKICAgIH0sCgogICAg5LqM57qnOiBhc3luYyBmdW5jdGlvbihpZHMpIHsKICAgICAgICBjb25zdCB7IHBkZmEsIHBkZmgsIHBkIH0gPSB0aGlzOwogICAgICAgIGxldCB1cmwgPSAoQXJyYXkuaXNBcnJheShpZHMpID8gaWRzWzBdIDogaWRzKS5yZXBsYWNlKC9bYCBdL2csICcnKTsKICAgICAgICB1cmwgPSB0aGlzLl9hYnModXJsKTsKICAgICAgICAKICAgICAgICBsZXQgaHRtbCA9IChhd2FpdCByZXEodXJsKSkuY29udGVudDsKICAgICAgICBsZXQgY292ZXIgPSB0aGlzLl9hYnMocGQoaHRtbCwgJy5zaW5nZXJfaW5mbyAucGljIGltZyYmc3JjJykpOwogICAgICAgIGxldCBjb250ZW50ID0gcGRmaChodG1sLCAnLnNpbmdlcl9pbmZvIC5saXN0X3IgLmluZm8gcCYmVGV4dCcpOwogICAgICAgIAogICAgICAgIGxldCB2b2QgPSB7CiAgICAgICAgICAgIHZvZF9uYW1lOiB0aGlzLl9jbGVhbihwZGZoKGh0bWwsICdoMSYmVGV4dCcpIHx8IHBkZmgoaHRtbCwgJ3RpdGxlJiZUZXh0JykpLAogICAgICAgICAgICB2b2RfcGljOiBjb3ZlciwKICAgICAgICAgICAgdm9kX3BsYXlfZnJvbTogJ+eIseeOqemfs+S5kCcsCiAgICAgICAgICAgIHZvZF9jb250ZW50OiBjb250ZW50IHx8ICcnLAogICAgICAgICAgICB2b2RfcmVtYXJrczogJycKICAgICAgICB9OwogICAgICAgIAogICAgICAgIGxldCBwbGF5X2xpc3QgPSBbXTsKICAgICAgICBsZXQgbWFrZUlkID0gKHUsIGxyYyA9ICcnKSA9PiBgJHt1fXx8fCR7Y292ZXJ9fHx8JHtscmN9YDsKICAgICAgICBsZXQgZ2V0THJjTGluayA9IChsaW5rKSA9PiB7CiAgICAgICAgICAgIGxldCBtYXRjaCA9IGxpbmsubWF0Y2goL1wvKHNvbmd8bXAzfHJhZGlvfHJhZGlvbGlzdHxyYWRpb3BsYXkpXC8oW14vXSspXC5odG1sLyk7CiAgICAgICAgICAgIHJldHVybiBtYXRjaCA/IHRoaXMuX2FicyhgL3BsdWcvZG93bi5waHA/YWM9bXVzaWMmbGs9bHJjJmlkPSR7bWF0Y2hbMl19YCkgOiAnJzsKICAgICAgICB9OwoKICAgICAgICBpZiAoL1wvKHZpZGVvfG1wNClcLyhbXi9dKylcLmh0bWwvLnRlc3QodXJsKSkgewogICAgICAgICAgICBsZXQgdmlkID0gdXJsLm1hdGNoKC9cLyh2aWRlb3xtcDQpXC8oW14vXSspXC5odG1sLylbMl07CiAgICAgICAgICAgIGxldCBxdWFsaXRpZXMgPSBbeyBuYW1lOiAn6JOd5YWJJywgcTogJzEwODAnIH0sIHsgbmFtZTogJ+i2hea4hScsIHE6ICc3MjAnIH0sIHsgbmFtZTogJ+mrmOa4hScsIHE6ICc0ODAnIH1dOwogICAgICAgICAgICBxdWFsaXRpZXMuZm9yRWFjaChxID0+IHsKICAgICAgICAgICAgICAgIHBsYXlfbGlzdC5wdXNoKGAke3EubmFtZX0kJHttYWtlSWQodGhpcy5fYWJzKGAvcGx1Zy9kb3duLnBocD9hYz12cGxheSZpZD0ke3ZpZH0mcT0ke3EucX1gKSl9YCk7CiAgICAgICAgICAgIH0pOwogICAgICAgIH0gCiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGxldCBpdGVtcyA9IHBkZmEoaHRtbCwgJy5wbGF5X2xpc3QmJmxpJykgfHwgW107CiAgICAgICAgICAgIGlmICghaXRlbXMubGVuZ3RoKSBpdGVtcyA9IHBkZmEoaHRtbCwgJy5zb25nX2xpc3QmJmxpJykgfHwgW107CiAgICAgICAgICAgIGlmICghaXRlbXMubGVuZ3RoKSBpdGVtcyA9IHBkZmEoaHRtbCwgJy5tdXNpY19saXN0JiZsaScpIHx8IFtdOwogICAgICAgICAgICBpZiAoIWl0ZW1zLmxlbmd0aCkgaXRlbXMgPSBwZGZhKGh0bWwsICd1bCYmbGknKSB8fCBbXTsKICAgICAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCAmJiAvXC8oc29uZ3xtcDN8cmFkaW98cmFkaW9saXN0fHJhZGlvcGxheSlcLy8udGVzdCh1cmwpKSB7CiAgICAgICAgICAgICAgICBwbGF5X2xpc3QucHVzaChg5pKt5pS+JCR7bWFrZUlkKHVybCwgZ2V0THJjTGluayh1cmwpKX1gKTsKICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBpdGVtcy5mb3JFYWNoKGl0ID0+IHsKICAgICAgICAgICAgICAgICAgICBsZXQgYSA9IHBkKGl0LCAnYSYmaHJlZicpOwogICAgICAgICAgICAgICAgICAgIGlmICghYSkgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIGlmICgvXC8oc29uZ3xtcDN8cmFkaW98cmFkaW9saXN0fHJhZGlvcGxheXx2aWRlb3xtcDQpXC8vLnRlc3QoYSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRpdGxlID0gdGhpcy5fY2xlYW4ocGRmaChpdCwgJy5uYW1lJiZUZXh0JykgfHwgcGQoaXQsICdhJiZUZXh0JykpOwogICAgICAgICAgICAgICAgICAgICAgICBwbGF5X2xpc3QucHVzaChgJHt0aXRsZX0kJHttYWtlSWQodGhpcy5fYWJzKGEpLCBnZXRMcmNMaW5rKGEpKX1gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB2b2Qudm9kX3BsYXlfdXJsID0gcGxheV9saXN0LmpvaW4oJyMnKTsKICAgICAgICByZXR1cm4gdm9kOwogICAgfSwKCiAgICBsYXp5OiBhc3luYyBmdW5jdGlvbihmbGFnLCBpZCwgZmxhZ3MpIHsKICAgICAgICBsZXQgW3VybCwgcGljLCBscmNVcmxdID0gaWQuc3BsaXQoJ3x8fCcpOwogICAgICAgIHVybCA9ICh1cmwgfHwgJycpLnJlcGxhY2UoL0AuKyQvLCAnJykudHJpbSgpOwogICAgICAgIGxldCBhcGlIZWFkZXJzID0gewogICAgICAgICAgICAnUmVmZXJlcic6IHRoaXMuaG9zdCArICcvJywKICAgICAgICAgICAgJ1VzZXItQWdlbnQnOiB0aGlzLmhlYWRlcnNbJ1VzZXItQWdlbnQnXQogICAgICAgIH07CgogICAgICAgIGxldCBwbGF5VXJsID0gJyc7CiAgICAgICAgbGV0IGlzVmlkZW8gPSB1cmwuaW5jbHVkZXMoJ2Rvd24ucGhwJykgJiYgdXJsLmluY2x1ZGVzKCdhYz12cGxheScpOwogICAgICAgIGlmIChpc1ZpZGVvKSB7CiAgICAgICAgICAgIGxldCByZXMgPSBhd2FpdCByZXEodXJsLCB7IG1ldGhvZDogJ0dFVCcsIHJlZGlyZWN0OiAwLCBoZWFkZXJzOiBhcGlIZWFkZXJzIH0pOwogICAgICAgICAgICBwbGF5VXJsID0gcmVzLmhlYWRlcnMuTG9jYXRpb24gfHwgcmVzLmhlYWRlcnMubG9jYXRpb24gfHwgdGhpcy5fcHJvY2Vzc19hcGlfcmVzcG9uc2UocmVzKTsKICAgICAgICB9CgogICAgICAgIGVsc2UgaWYgKC9cLyhzb25nfG1wM3xyYWRpb3xyYWRpb2xpc3R8cmFkaW9wbGF5KVwvKFteL10rKVwuaHRtbC8udGVzdCh1cmwpKSB7CiAgICAgICAgICAgIGxldCBtaWQgPSB1cmwubWF0Y2goL1wvKFteL10rKVwuaHRtbC8pWzFdOwogICAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgcmVxKHRoaXMuX2FicygnL2pzL3BsYXkucGhwJyksIHsKICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLAogICAgICAgICAgICAgICAgaGVhZGVyczogewogICAgICAgICAgICAgICAgICAgIC4uLmFwaUhlYWRlcnMsCiAgICAgICAgICAgICAgICAgICAgJ1gtUmVxdWVzdGVkLVdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnLAogICAgICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIGRhdGE6IHsgaWQ6IG1pZCwgdHlwZTogJ211c2ljJyB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBwbGF5VXJsID0gdGhpcy5fcHJvY2Vzc19hcGlfcmVzcG9uc2UocmVzKTsKICAgICAgICB9CgogICAgICAgIGxldCBmaW5hbFVybCA9IHRoaXMuX2FicyhwbGF5VXJsIHx8IHVybCk7CiAgICAgICAgbGV0IHBsYXllckhlYWRlcnMgPSB7CiAgICAgICAgICAgICdVc2VyLUFnZW50JzogYXBpSGVhZGVyc1snVXNlci1BZ2VudCddLAogICAgICAgICAgICAuLi4oZmluYWxVcmwuaW5jbHVkZXMoJzIyYTUuY29tJykgJiYgeyAnUmVmZXJlcic6IGFwaUhlYWRlcnNbJ1JlZmVyZXInXSB9KQogICAgICAgIH07CgogICAgICAgIGlmIChpc1ZpZGVvKSB7CiAgICAgICAgICAgIHJldHVybiB7IHBhcnNlOiAwLCB1cmw6IGZpbmFsVXJsLCBoZWFkZXI6IHBsYXllckhlYWRlcnMgfTsKICAgICAgICB9CgogICAgICAgIGxldCBjb3ZlciA9ICcnOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCBwYWdlUmVzID0gYXdhaXQgcmVxKHVybCwgeyBoZWFkZXJzOiBhcGlIZWFkZXJzIH0pOwogICAgICAgICAgICBsZXQgcGFnZUh0bWwgPSB0eXBlb2YgcGFnZVJlcyA9PT0gJ29iamVjdCcgPyBwYWdlUmVzLmNvbnRlbnQgOiBwYWdlUmVzOwogICAgICAgICAgICBsZXQgb2dJbWFnZU1hdGNoID0gcGFnZUh0bWwubWF0Y2goLzxtZXRhW14+XStwcm9wZXJ0eT0ib2c6aW1hZ2UiW14+XStjb250ZW50PSIoW14iXSspIltePl0qPi9pKTsKICAgICAgICAgICAgaWYgKG9nSW1hZ2VNYXRjaCAmJiBvZ0ltYWdlTWF0Y2hbMV0pIHsKICAgICAgICAgICAgICAgIGNvdmVyID0gb2dJbWFnZU1hdGNoWzFdOwogICAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCB7fQoKICAgICAgICBsZXQgbHJjRGF0YSA9ICcnOwogICAgICAgIGlmIChscmNVcmwpIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIGxldCBscmNSZXMgPSBhd2FpdCByZXEobHJjVXJsLCB7IGhlYWRlcnM6IGFwaUhlYWRlcnMgfSk7CiAgICAgICAgICAgICAgICBsZXQgY29udGVudCA9IHR5cGVvZiBscmNSZXMgPT09ICdvYmplY3QnID8gbHJjUmVzLmNvbnRlbnQgOiBscmNSZXM7CiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnICYmIGNvbnRlbnQuaW5jbHVkZXMoJ1snKSAmJiBjb250ZW50LmluY2x1ZGVzKCddJykpIHsKICAgICAgICAgICAgICAgICAgICBscmNEYXRhID0gY29udGVudDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBjYXRjaCB7fQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcGFyc2U6IDAsCiAgICAgICAgICAgIHVybDogZmluYWxVcmwsCiAgICAgICAgICAgIGhlYWRlcjogcGxheWVySGVhZGVycywKICAgICAgICAgICAgbHJjOiBscmNEYXRhLAogICAgICAgICAgICBwaWM6IGNvdmVyLAogICAgICAgICAgICBjb3ZlcjogY292ZXIsCiAgICAgICAgICAgIGhlaWdodDogNzIwCiAgICAgICAgfTsKICAgIH0sCgogICAgX3Byb2Nlc3NfYXBpX3Jlc3BvbnNlOiAocmVzKSA9PiB7CiAgICAgICAgaWYgKCFyZXMpIHJldHVybiAnJzsKICAgICAgICBjb25zdCBjb250ZW50ID0gdHlwZW9mIHJlcyA9PT0gJ29iamVjdCcgPyByZXMuY29udGVudCA6IHJlczsKICAgICAgICBjb25zdCB0cmltbWVkID0gY29udGVudC50cmltKCk7CiAgICAgICAgbGV0IGpzb247CiAgICAgICAgdHJ5IHsganNvbiA9IEpTT04ucGFyc2UoY29udGVudCk7IH0gY2F0Y2gge30gCiAgICAgICAgcmV0dXJuIGpzb24/LnVybCA/IGpzb24udXJsLnJlcGxhY2UoL1xcXC8vZywgJy8nKSA6ICh0cmltbWVkLnN0YXJ0c1dpdGgoJ2h0dHAnKSA/IHRyaW1tZWQgOiAnJyk7CiAgICB9Cn07 \ No newline at end of file diff --git "a/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" "b/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" index 6a2a6720..92050aca 100644 --- "a/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" +++ "b/spider/js/\347\261\263\345\205\224\351\237\263\344\271\220[\345\220\254].js" @@ -9,51 +9,4 @@ }) */ -var rule = { - title: '米兔音乐', - host: 'https://api.qqmp3.vip', - url: '/api/fyclass', - searchUrl: '/api/songs.php?type=search&keyword=**', - class_name: '热门歌曲&新歌曲&随机歌曲', - class_url: 'songs.php&songs.php?type=new&songs.php?type=rand', - searchable: 2, - quickSearch: 0, - filterable: 0, - play_parse: true, - limit: 6, - double: true, - headers: { - 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; V2284A Build/V417IR; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Safari/537.36', - 'Accept': '*/*', - 'Origin': 'https://www.qqmp3.vip', - 'referer': 'https://www.qqmp3.vip', - 'x-requested-with': 'com.mmbox.xbrowser', - 'Sec-Fetch-Site': 'same-site', - 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Dest': 'empty', - 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' - }, - 推荐: '*', - 一级: 'json:data;name;pic;artist;rid', - 二级: '*', - 搜索: 'json:data;name;pic;artist;rid', - lazy: async function() { - let ridMatch = this.input.match(/api\/([^/?]+)/); - if (!ridMatch) return this.input; - let rid = ridMatch[1]; - let api = 'https://api.qqmp3.vip/api/kw.php?rid=' + rid; - // console.log('解析接口:', api); - let json = await request(api); - let data = JSON.parse(json); - if (data.code === 200 && data.data?.url) { - return { - parse: 0, - url: data.data.url, - header: this.headers, - lrc: data.data.lrc || '', - playMode: 'repeat' - }; - } - return this.input; - }, -}; \ No newline at end of file +dmFyIHJ1bGUgPSB7CiAgdGl0bGU6ICfnsbPlhZTpn7PkuZAnLAogIGhvc3Q6ICdodHRwczovL2FwaS5xcW1wMy52aXAnLAogIHVybDogJy9hcGkvZnljbGFzcycsCiAgc2VhcmNoVXJsOiAnL2FwaS9zb25ncy5waHA/dHlwZT1zZWFyY2gma2V5d29yZD0qKicsCiAgY2xhc3NfbmFtZTogJ+eDremXqOatjOabsibmlrDmrYzmm7Im6ZqP5py65q2M5puyJywKICBjbGFzc191cmw6ICdzb25ncy5waHAmc29uZ3MucGhwP3R5cGU9bmV3JnNvbmdzLnBocD90eXBlPXJhbmQnLAogIHNlYXJjaGFibGU6IDIsCiAgcXVpY2tTZWFyY2g6IDAsCiAgZmlsdGVyYWJsZTogMCwKICBwbGF5X3BhcnNlOiB0cnVlLAogIGxpbWl0OiA2LAogIGRvdWJsZTogdHJ1ZSwKICBoZWFkZXJzOiB7CiAgICAnVXNlci1BZ2VudCc6ICdNb3ppbGxhLzUuMCAoTGludXg7IEFuZHJvaWQgMTI7IFYyMjg0QSBCdWlsZC9WNDE3SVI7IHd2KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBWZXJzaW9uLzQuMCBDaHJvbWUvMTAxLjAuNDk1MS42MSBTYWZhcmkvNTM3LjM2JywKICAgICdBY2NlcHQnOiAnKi8qJywKICAgICdPcmlnaW4nOiAnaHR0cHM6Ly93d3cucXFtcDMudmlwJywKICAgICdyZWZlcmVyJzogJ2h0dHBzOi8vd3d3LnFxbXAzLnZpcCcsCiAgICAneC1yZXF1ZXN0ZWQtd2l0aCc6ICdjb20ubW1ib3gueGJyb3dzZXInLAogICAgJ1NlYy1GZXRjaC1TaXRlJzogJ3NhbWUtc2l0ZScsCiAgICAnU2VjLUZldGNoLU1vZGUnOiAnY29ycycsCiAgICAnU2VjLUZldGNoLURlc3QnOiAnZW1wdHknLAogICAgJ0FjY2VwdC1MYW5ndWFnZSc6ICd6aC1DTix6aDtxPTAuOSxlbi1VUztxPTAuOCxlbjtxPTAuNycKICB9LAogIOaOqOiNkDogJyonLAogIOS4gOe6pzogJ2pzb246ZGF0YTtuYW1lO3BpYzthcnRpc3Q7cmlkJywKICDkuoznuqc6ICcqJywKICDmkJzntKI6ICdqc29uOmRhdGE7bmFtZTtwaWM7YXJ0aXN0O3JpZCcsCiAgbGF6eTogYXN5bmMgZnVuY3Rpb24oKSB7CiAgICBsZXQgcmlkTWF0Y2ggPSB0aGlzLmlucHV0Lm1hdGNoKC9hcGlcLyhbXi8/XSspLyk7CiAgICBpZiAoIXJpZE1hdGNoKSByZXR1cm4gdGhpcy5pbnB1dDsKICAgIGxldCByaWQgPSByaWRNYXRjaFsxXTsKICAgIGxldCBhcGkgPSAnaHR0cHM6Ly9hcGkucXFtcDMudmlwL2FwaS9rdy5waHA/cmlkPScgKyByaWQ7CiAgLy8gIGNvbnNvbGUubG9nKCfop6PmnpDmjqXlj6M6JywgYXBpKTsKICAgIGxldCBqc29uID0gYXdhaXQgcmVxdWVzdChhcGkpOwogICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGpzb24pOwogICAgaWYgKGRhdGEuY29kZSA9PT0gMjAwICYmIGRhdGEuZGF0YT8udXJsKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcGFyc2U6IDAsCiAgICAgICAgICAgIHVybDogZGF0YS5kYXRhLnVybCwKICAgICAgICAgICAgaGVhZGVyOiB0aGlzLmhlYWRlcnMsCiAgICAgICAgICAgIGxyYzogZGF0YS5kYXRhLmxyYyB8fCAnJywKICAgICAgICAgICAgcGxheU1vZGU6ICdyZXBlYXQnCiAgICAgICAgfTsKICAgIH0KICAgIHJldHVybiB0aGlzLmlucHV0OwogIH0sCn07 \ No newline at end of file From 5a955fce36b3eb4a7b2b4311ec398e41232f8490 Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 21 Jan 2026 16:20:58 +0800 Subject: [PATCH 55/99] =?UTF-8?q?Change=20all=20const=20to=20let=20in=20?= =?UTF-8?q?=E9=BA=BB=E9=9B=80=E8=A7=86=E9=A2=91.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\272\273\351\233\200\350\247\206\351\242\221.js" | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 "spider/js/\351\272\273\351\233\200\350\247\206\351\242\221.js" diff --git "a/spider/js/\351\272\273\351\233\200\350\247\206\351\242\221.js" "b/spider/js/\351\272\273\351\233\200\350\247\206\351\242\221.js" new file mode 100644 index 00000000..b63b250d --- /dev/null +++ "b/spider/js/\351\272\273\351\233\200\350\247\206\351\242\221.js" @@ -0,0 +1,13 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 0, + title: '麻雀视频', + author: 'EylinSir', + '类型': '影视', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflvbHop4YnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfpurvpm4Dop4bpopEnLAogICAgaG9zdDogJ2h0dHBzOi8vd3d3Lm1xdHYuY2MnLAogICAgaG9tZVVybDogJ2h0dHBzOi8vd3d3Lm1xdHYuY2MnLAogICAgdXJsOiAnL2xpYnMvVm9kTGlzdC5hcGkucGhwP3R5cGU9ZnljbGFzcyZyYW5rPXJhbmtob3QmY2F0PSZ5ZWFyPSZhcmVhPSZwYWdlPWZ5cGFnZSZ0b2tlbj1meXRva2VuJywKICAgIHNlYXJjaFVybDogJy9saWJzL1ZvZExpc3QuYXBpLnBocD9zZWFyY2g9KiomdG9rZW49Znl0b2tlbicsCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDAsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgdGltZW91dDogMTAwMDAsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAga2V5OiAnTWN4b3NAbXVjaG8hbm1tZScsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgJ1VzZXItQWdlbnQnOiAnTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzE0Mi4wLjAuMCBTYWZhcmkvNTM3LjM2JywKICAgICAgICAnYWNjZXB0LWxhbmd1YWdlJzogJ3poLUNOLHpoO3E9MC45JywKICAgICAgICAnc2VjLWNoLXVhJzogJyJHb29nbGUgQ2hyb21lIjt2PSIxNDMiLCAiQ2hyb21pdW0iO3Y9IjE0MyIsICJOb3QgQShCcmFuZCI7dj0iMjQiJywKICAgICAgICAnY2FjaGUtY29udHJvbCc6ICduby1jYWNoZScsCiAgICAgICAgJ3ByYWdtYSc6ICduby1jYWNoZScsCiAgICAgICAgJ3NlYy1jaC11YS1tb2JpbGUnOiAnPzAnLAogICAgICAgICdzZWMtY2gtdWEtcGxhdGZvcm0nOiAnIldpbmRvd3MiJywKICAgICAgICAnc2VjLWZldGNoLXNpdGUnOiAnc2FtZS1vcmlnaW4nCiAgICB9LAogICAgCiAgICBnZXRUb2tlbjogYXN5bmMgZnVuY3Rpb24gKHBhdGgsIHJlZlBhdGggPSAnJykgewogICAgICAgIGxldCBoZWFkZXJzID0gewogICAgICAgICAgICAuLi50aGlzLmhlYWRlcnMsCiAgICAgICAgICAgICdBY2NlcHQnOiAndGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksaW1hZ2UvYXZpZixpbWFnZS93ZWJwLGltYWdlL2FwbmcsKi8qO3E9MC44LGFwcGxpY2F0aW9uL3NpZ25lZC1leGNoYW5nZTt2PWIzO3E9MC43JywKICAgICAgICAgICAgJ3ByaW9yaXR5JzogJ3U9MCwgaScsCiAgICAgICAgICAgICdzZWMtZmV0Y2gtZGVzdCc6ICdkb2N1bWVudCcsCiAgICAgICAgICAgICdzZWMtZmV0Y2gtbW9kZSc6ICduYXZpZ2F0ZScsCiAgICAgICAgICAgICdzZWMtZmV0Y2gtdXNlcic6ICc/MScsCiAgICAgICAgICAgICd1cGdyYWRlLWluc2VjdXJlLXJlcXVlc3RzJzogJzEnCiAgICAgICAgfTsKICAgICAgICBpZiAocmVmUGF0aCkgaGVhZGVyc1sncmVmZXJlciddID0gYCR7dGhpcy5ob3N0fSR7cmVmUGF0aH1gOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKGAke3RoaXMuaG9zdH0ke3BhdGh9YCwgeyBoZWFkZXJzIH0pOwogICAgICAgIGxldCBodG1sID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgbGV0IG1hdGNoID0gaHRtbC5tYXRjaCgvd2luZG93XC5wYWdlaWRccz89XHM/JyguKj8pJzsvaSk7CiAgICAgICAgbGV0IHBhZ2VJZCA9IG1hdGNoID8gbWF0Y2hbMV0gOiAnJzsKICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGVEYXRhKHBhZ2VJZCk7CiAgICB9LAoKICAgIGVuY29kZURhdGE6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgbGV0IGpzb25TdHIgPSBKU09OLnN0cmluZ2lmeShkYXRhKTsKICAgICAgICBsZXQgYjY0XzEgPSBidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChqc29uU3RyKSkpOwogICAgICAgIGxldCB4b3JfcmVzdWx0ID0gJyc7CiAgICAgICAgbGV0IGtleUxlbiA9IHRoaXMua2V5Lmxlbmd0aDsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGI2NF8xLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIGxldCBjaGFyQ29kZSA9IGI2NF8xLmNoYXJDb2RlQXQoaSkgXiB0aGlzLmtleS5jaGFyQ29kZUF0KGkgJSBrZXlMZW4pOwogICAgICAgICAgICB4b3JfcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUpOwogICAgICAgIH0KICAgICAgICBsZXQgYjY0XzIgPSBidG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh4b3JfcmVzdWx0KSkpOwogICAgICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoYjY0XzIpOwogICAgfSwKCiAgICBkZWNvZGVEYXRhOiBmdW5jdGlvbiAoZW5jb2RlZFN0cikgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCBiYXNlNjREZWNvZGUgPSAoc3RyKSA9PiB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGF0b2Ioc3RyKSkpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGxldCBkZWNvZGVkU3RlcDFTdHIgPSBiYXNlNjREZWNvZGUoZW5jb2RlZFN0cik7CiAgICAgICAgICAgIGxldCB4b3JSZXN1bHQgPSAnJzsKICAgICAgICAgICAgbGV0IGtleUxlbiA9IHRoaXMua2V5Lmxlbmd0aDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZWNvZGVkU3RlcDFTdHIubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHhvclJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGRlY29kZWRTdGVwMVN0ci5jaGFyQ29kZUF0KGkpIF4gdGhpcy5rZXkuY2hhckNvZGVBdChpICUga2V5TGVuKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGxldCBkZWNvZGVkU3RlcDJTdHIgPSBiYXNlNjREZWNvZGUoeG9yUmVzdWx0KTsKICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlZFN0ZXAyU3RyKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0RlY29kZSBlcnJvcjonLCBlKTsKICAgICAgICAgICAgcmV0dXJuIHt9OwogICAgICAgIH0KICAgIH0sCiAgICAKICAgIGdldEhlYWRlcnMyOiBmdW5jdGlvbiAocmVmUGF0aCA9ICcnKSB7CiAgICAgICAgbGV0IGhlYWRlcnMgPSB7CiAgICAgICAgICAgIC4uLnRoaXMuaGVhZGVycywKICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQsICovKjsgcT0wLjAxJywKICAgICAgICAgICAgJ3ByaW9yaXR5JzogJ3U9MSwgaScsCiAgICAgICAgICAgICdzZWMtZmV0Y2gtZGVzdCc6ICdlbXB0eScsCiAgICAgICAgICAgICdzZWMtZmV0Y2gtbW9kZSc6ICdjb3JzJywKICAgICAgICAgICAgJ3gtcmVxdWVzdGVkLXdpdGgnOiAnWE1MSHR0cFJlcXVlc3QnCiAgICAgICAgfTsKICAgICAgICBpZiAocmVmUGF0aCkgaGVhZGVyc1sncmVmZXJlciddID0gYCR7dGhpcy5ob3N0fSR7cmVmUGF0aH1gOwogICAgICAgIHJldHVybiBoZWFkZXJzOwogICAgfSwKCiAgICBhcnIydm9kczogZnVuY3Rpb24gKGFycikgewogICAgICAgIHJldHVybiAoYXJyIHx8IFtdKS5tYXAoaSA9PiAoewogICAgICAgICAgICB0aXRsZTogaS50aXRsZSwKICAgICAgICAgICAgdXJsOiBgJHt0aGlzLmhvc3R9JHtpLnVybH1gLAogICAgICAgICAgICBkZXNjOiBpLnJlbWFyaywKICAgICAgICAgICAgcGljX3VybDogaS5pbWcsCiAgICAgICAgICAgIHZvZF95ZWFyOiBpLnllYXIgfHwgJycKICAgICAgICB9KSk7CiAgICB9LAogICAgCiAgICDpooTlpITnkIY6IGFzeW5jIGZ1bmN0aW9uICgpIHt9LAoKICAgIGNsYXNzX3BhcnNlOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgY2xhc3M6IFsKICAgICAgICAgICAgICAgIHsgJ3R5cGVfaWQnOiAnL3R5cGUvbW92aWUnLCAndHlwZV9uYW1lJzogJ+eUteW9sScgfSwKICAgICAgICAgICAgICAgIHsgJ3R5cGVfaWQnOiAnL3R5cGUvdHYnLCAndHlwZV9uYW1lJzogJ+eUteinhuWJpycgfSwKICAgICAgICAgICAgICAgIHsgJ3R5cGVfaWQnOiAnL3R5cGUvdmEnLCAndHlwZV9uYW1lJzogJ+e7vOiJuicgfSwKICAgICAgICAgICAgICAgIHsgJ3R5cGVfaWQnOiAnL3R5cGUvY3QnLCAndHlwZV9uYW1lJzogJ+WKqOa8qycgfQogICAgICAgICAgICBdLAogICAgICAgICAgICBmaWx0ZXJzOiB7fQogICAgICAgIH07CiAgICB9LAogICAgCiAgICDmjqjojZA6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdG9rZW4gPSBhd2FpdCB0aGlzLmdldFRva2VuKCcvJyk7CiAgICAgICAgbGV0IHVybCA9IGAke3RoaXMuaG9zdH0vbGlicy9Wb2RMaXN0LmFwaS5waHA/aG9tZT1pbmRleCZ0b2tlbj0ke3Rva2VufWA7CiAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2godXJsLCB7IGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVyczIoJy8nKSB9KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzcC50ZXh0KCkpOwogICAgICAgIGxldCB2aWRlb3MgPSBbXTsKICAgICAgICBpZiAoanNvbi5kYXRhICYmIGpzb24uZGF0YS5tb3ZpZSkgewogICAgICAgICAgICBmb3IgKGxldCBpIG9mIGpzb24uZGF0YS5tb3ZpZSkgewogICAgICAgICAgICAgICAgdmlkZW9zLnB1c2goLi4udGhpcy5hcnIydm9kcyhpLnNob3cpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uICh0aWQsIHBnLCBmaWx0ZXIsIGV4dGVuZCkgewogICAgICAgIGxldCB0eXBlS2V5ID0gdGlkLnNwbGl0KCcvJylbMl07CiAgICAgICAgbGV0IHRva2VuID0gYXdhaXQgdGhpcy5nZXRUb2tlbih0aWQsICcvJyk7CiAgICAgICAgbGV0IHVybCA9IGAke3RoaXMuaG9zdH0vbGlicy9Wb2RMaXN0LmFwaS5waHA/dHlwZT0ke3R5cGVLZXl9JnJhbms9cmFua2hvdCZjYXQ9JnllYXI9JmFyZWE9JnBhZ2U9JHtwZ30mdG9rZW49JHt0b2tlbn1gOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMyKHRpZCkgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgdmlkZW9zID0gdGhpcy5hcnIydm9kcyhqc29uLmRhdGEpOwogICAgICAgIHJldHVybiBzZXRSZXN1bHQodmlkZW9zKTsKICAgIH0sCiAgICAKICAgIOS6jOe6pzogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBpZCA9IHRoaXMuaW5wdXQucmVwbGFjZShgJHt0aGlzLmhvc3R9YCwgJycpOwogICAgICAgIGxldCByZWFsSWQgPSBpZC5zcGxpdCgnLycpW2lkLnNwbGl0KCcvJykubGVuZ3RoIC0gMV07CiAgICAgICAgbGV0IHRva2VuID0gYXdhaXQgdGhpcy5nZXRUb2tlbihpZCwgJy8nKTsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9saWJzL1ZvZEluZm8uYXBpLnBocD90eXBlPWN0JmlkPSR7cmVhbElkfSZ0b2tlbj0ke3Rva2VufWA7CiAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2godXJsLCB7IGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVyczIoaWQpIH0pOwogICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCByZXNwLnRleHQoKSk7CiAgICAgICAgbGV0IGRhdGEgPSBqc29uLmRhdGE7CiAgICAgICAgbGV0IHBsYXlBcGkgPSBkYXRhLnBsYXlhcGkgfHwgW107CiAgICAgICAgbGV0IHBhcnNlcyA9IHBsYXlBcGkKICAgICAgICAgICAgLmZpbHRlcihpID0+IHR5cGVvZiBpID09PSAnb2JqZWN0JyAmJiBpICE9PSBudWxsICYmIGkudXJsICYmIHR5cGVvZiBpLnVybCA9PT0gJ3N0cmluZycpCiAgICAgICAgICAgIC5tYXAoaSA9PiBpLnVybC5zdGFydHNXaXRoKCcvLycpID8gYGh0dHBzOiR7aS51cmx9YCA6IGkudXJsKQogICAgICAgICAgICAuam9pbignLCcpOwogICAgICAgIGxldCBzaG93cyA9IFtdOwogICAgICAgIGxldCBwbGF5VXJscyA9IFtdOwogICAgICAgIGlmIChkYXRhLnBsYXlpbmZvKSB7CiAgICAgICAgICAgIGZvciAobGV0IGogb2YgZGF0YS5wbGF5aW5mbykgewogICAgICAgICAgICAgICAgbGV0IHVybHMgPSBbXTsKICAgICAgICAgICAgICAgIGZvciAobGV0IGsgb2Ygai5wbGF5ZXIpIHsKICAgICAgICAgICAgICAgICAgICB1cmxzLnB1c2goYCR7ay5ub30kJHtrLnVybH1AJHtwYXJzZXN9YCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodXJscy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgcGxheVVybHMucHVzaCh1cmxzLmpvaW4oJyMnKSk7CiAgICAgICAgICAgICAgICAgICAgc2hvd3MucHVzaChqLmNuc2l0ZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbGV0IFZPRCA9IHsKICAgICAgICAgICAgdm9kX2lkOiBpZCwKICAgICAgICAgICAgdm9kX25hbWU6IGRhdGEudGl0bGUsCiAgICAgICAgICAgIHZvZF9waWM6IGRhdGEuaW1nLAogICAgICAgICAgICB2b2RfcmVtYXJrczogZGF0YS5yZW1hcmssCiAgICAgICAgICAgIHZvZF95ZWFyOiBkYXRhLnllYXIsCiAgICAgICAgICAgIHZvZF9hcmVhOiBkYXRhLmFyZWEsCiAgICAgICAgICAgIHZvZF9hY3RvcjogZGF0YS5hY3RvciwKICAgICAgICAgICAgdm9kX2RpcmVjdG9yOiBkYXRhLmRpcmVjdG9yLAogICAgICAgICAgICB2b2RfY29udGVudDogJycsCiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206IHNob3dzLmpvaW4oJyQkJCcpLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHBsYXlVcmxzLmpvaW4oJyQkJCcpLAogICAgICAgICAgICB0eXBlX25hbWU6ICcnCiAgICAgICAgfTsKICAgICAgICByZXR1cm4gVk9EOwogICAgfSwKICAgIAogICAg5pCc57SiOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgbGV0IHBhdGggPSBgL3NlYXJjaC8ke2VuY29kZVVSSUNvbXBvbmVudCh0aGlzLktFWSl9YDsKICAgICAgICBsZXQgdG9rZW4gPSBhd2FpdCB0aGlzLmdldFRva2VuKHBhdGgsICcvJyk7CiAgICAgICAgbGV0IHVybCA9IGAke3RoaXMuaG9zdH0vbGlicy9Wb2RMaXN0LmFwaS5waHA/c2VhcmNoPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuS0VZKX0mdG9rZW49JHt0b2tlbn1gOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMyKHBhdGgpIH0pOwogICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCByZXNwLnRleHQoKSk7CiAgICAgICAgbGV0IGRlY29kZURhdGEgPSB0aGlzLmRlY29kZURhdGEoanNvbi5kYXRhKTsKICAgICAgICBsZXQgdmlkZW9zID0gW107CiAgICAgICAgaWYgKGRlY29kZURhdGEudm9kX2FsbCkgewogICAgICAgICAgICBmb3IgKGxldCBpIG9mIGRlY29kZURhdGEudm9kX2FsbCkgewogICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpID09PSAnb2JqZWN0JyAmJiBpICE9PSBudWxsKSB7CiAgICAgICAgICAgICAgICAgICAgdmlkZW9zLnB1c2goLi4udGhpcy5hcnIydm9kcyhpLnNob3cpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICBsYXp5OiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgbGV0IFtyYXdVcmwsIHBhcnNlc1N0ciA9ICcnXSA9IHRoaXMuaW5wdXQuc3BsaXQoJ0AnKTsKICAgICAgICBsZXQgcGFyc2VzID0gcGFyc2VzU3RyLnNwbGl0KCcsJyk7CiAgICAgICAgbGV0IGp4ID0gMDsKICAgICAgICBsZXQgc25pZmYgPSAwOwogICAgICAgIGxldCB1cmwgPSAnJzsKICAgICAgICBpZiAocmF3VXJsLnN0YXJ0c1dpdGgoJ2h0dHAnKSAmJiAvKD86d3d3XC5pcWl5aXx2XC5xcXx2XC55b3VrdXx3d3dcLm1ndHZ8d3d3XC5iaWxpYmlsaSlcLmNvbS8udGVzdChyYXdVcmwpKSB7CiAgICAgICAgICAgIHVybCA9IHJhd1VybDsKICAgICAgICAgICAganggPSAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGxldCBmaXJzdFZhbGlkUGFyc2UgPSBwYXJzZXMuZmluZChqID0+IGouc3RhcnRzV2l0aCgnaHR0cCcpKTsKICAgICAgICAgICAgaWYgKGZpcnN0VmFsaWRQYXJzZSkgewogICAgICAgICAgICAgICAgdXJsID0gYCR7Zmlyc3RWYWxpZFBhcnNlfSR7cmF3VXJsfWA7CiAgICAgICAgICAgICAgICBzbmlmZiA9IDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1cmwgPSByYXdVcmw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcGFyc2U6IHNuaWZmIHx8IGp4LAogICAgICAgICAgICB1cmwsCiAgICAgICAgICAgIGhlYWRlcjogeyAnVXNlci1BZ2VudCc6IHRoaXMuaGVhZGVyc1snVXNlci1BZ2VudCddIH0KICAgICAgICB9OwogICAgfQp9Ow== \ No newline at end of file From b2cad32883f96ed705778961b6d2e21eeff67fca Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 21 Jan 2026 16:21:53 +0800 Subject: [PATCH 56/99] Update multiple files --- "spider/js/3Q\345\275\261\350\247\206.js" | 13 + ...\345\233\255\350\241\214[\346\210\217].js" | 249 +----------------- ...55\346\222\255\345\275\261\350\247\206.js" | 13 + ...\345\260\217\350\257\264[\344\271\246].js" | 1 + ...\347\225\205\345\220\254[\345\220\254].js" | 3 +- ...\347\237\255\345\211\247[\347\237\255].js" | 3 +- ...75\346\226\260\345\244\247\345\205\250.js" | 13 + 7 files changed, 45 insertions(+), 250 deletions(-) create mode 100644 "spider/js/3Q\345\275\261\350\247\206.js" create mode 100644 "spider/js/\347\203\255\346\222\255\345\275\261\350\247\206.js" create mode 100644 "spider/js/\350\277\275\346\226\260\345\244\247\345\205\250.js" diff --git "a/spider/js/3Q\345\275\261\350\247\206.js" "b/spider/js/3Q\345\275\261\350\247\206.js" new file mode 100644 index 00000000..7236e339 --- /dev/null +++ "b/spider/js/3Q\345\275\261\350\247\206.js" @@ -0,0 +1,13 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 0, + title: '3Q影视', + author: 'EylinSir', + '类型': '影视', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflvbHop4YnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICczUeW9seinhicsCiAgICBkZXNjOiAnM1HlvbHop4bmupAnLAogICAgaG9zdDogJ2h0dHBzOi8vcXFxeXMuY29tJywKICAgIGhvbWVVcmw6ICdodHRwczovL3FxcXlzLmNvbScsCiAgICB1cmw6ICcvYXBpLnBocC9maWx0ZXIvdm9kP3R5cGVfbmFtZT1meWNsYXNzJnBhZ2U9ZnlwYWdlJnNvcnQ9aGl0cycsCiAgICBzZWFyY2hVcmw6ICcvYXBpLnBocC9zZWFyY2gvaW5kZXg/d2Q9KiomcGFnZT1meXBhZ2UmbGltaXQ9MTUnLAogICAgc2VhcmNoYWJsZTogMSwKICAgIHF1aWNrU2VhcmNoOiAwLAogICAgZmlsdGVyYWJsZTogMSwKICAgIHRpbWVvdXQ6IDEwMDAwLAogICAgcGxheV9wYXJzZTogdHJ1ZSwKICAgIGhlYWRlcnM6IHsKICAgICAgICAnVXNlci1BZ2VudCc6ICdNb3ppbGxhLzUuMCAoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvMTQyLjAuMC4wIFNhZmFyaS81MzcuMzYnLAogICAgICAgICdhY2NlcHQtbGFuZ3VhZ2UnOiAnemgtQ04semg7cT0wLjknLAogICAgICAgICdjYWNoZS1jb250cm9sJzogJ25vLWNhY2hlJywKICAgICAgICAncHJhZ21hJzogJ25vLWNhY2hlJywKICAgICAgICAncHJpb3JpdHknOiAndT0xLCBpJywKICAgICAgICAnc2VjLWNoLXVhJzogJyJDaHJvbWl1bSI7dj0iMTQyIiwgIkdvb2dsZSBDaHJvbWUiO3Y9IjE0MiIsICJOb3RfQSBCcmFuZCI7dj0iOTkiJywKICAgICAgICAnc2VjLWNoLXVhLW1vYmlsZSc6ICI/MCIsCiAgICAgICAgJ3NlYy1jaC11YS1wbGF0Zm9ybSc6ICciV2luZG93cyInLAogICAgICAgICdzZWMtZmV0Y2gtZGVzdCc6ICJlbXB0eSIsCiAgICAgICAgJ3NlYy1mZXRjaC1tb2RlJzogImNvcnMiLAogICAgICAgICdzZWMtZmV0Y2gtc2l0ZSc6ICJzYW1lLW9yaWdpbiIKICAgIH0sCiAgICAKCgogICAganNvbjJ2b2RzOiBmdW5jdGlvbiAoYXJyKSB7CiAgICAgICAgbGV0IHZpZGVvcyA9IFtdOwogICAgICAgIGZvciAoY29uc3QgaSBvZiBhcnIpIHsKICAgICAgICAgICAgbGV0IHR5cGVfbmFtZSA9IGkudHlwZV9uYW1lIHx8ICcnOwogICAgICAgICAgICBpZiAoaS52b2RfY2xhc3MpIHsKICAgICAgICAgICAgICAgIHR5cGVfbmFtZSA9IHR5cGVfbmFtZSArICcsJyArIGkudm9kX2NsYXNzOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZpZGVvcy5wdXNoKHsKICAgICAgICAgICAgICAgIHRpdGxlOiBpLnZvZF9uYW1lLAogICAgICAgICAgICAgICAgdXJsOiBgJHt0aGlzLmhvc3R9L2FwaS5waHAvdm9kL2dldF9kZXRhaWw/dm9kX2lkPSR7aS52b2RfaWR9YCwKICAgICAgICAgICAgICAgIGRlc2M6IGkudm9kX3JlbWFya3MsCiAgICAgICAgICAgICAgICBwaWNfdXJsOiBpLnZvZF9waWMsCiAgICAgICAgICAgICAgICB2b2RfeWVhcjogaS52b2RfeWVhciwKICAgICAgICAgICAgICAgIHR5cGVfbmFtZTogdHlwZV9uYW1lCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdmlkZW9zOwogICAgfSwKICAgIAogICAg6aKE5aSE55CGOiBhc3luYyBmdW5jdGlvbiAoKSB7fSwKICAgIAogICAgY2xhc3NfcGFyc2U6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9hcGkucGhwL2luZGV4L2hvbWVgOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgY2F0ZWdvcmllcyA9IGpzb24uZGF0YS5jYXRlZ29yaWVzOwogICAgICAgIGxldCBjbGFzc2VzID0gW107CiAgICAgICAgZm9yIChjb25zdCBpIG9mIGNhdGVnb3JpZXMpIHsKICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHsKICAgICAgICAgICAgICAgIHR5cGVfaWQ6IGkudHlwZV9uYW1lLAogICAgICAgICAgICAgICAgdHlwZV9uYW1lOiBpLnR5cGVfbmFtZQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgY2xhc3M6IGNsYXNzZXMsIGZpbHRlcnM6IHt9IH07CiAgICB9LAogICAgCiAgICDmjqjojZA6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9hcGkucGhwL2luZGV4L2hvbWVgOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgY2F0ZWdvcmllcyA9IGpzb24uZGF0YS5jYXRlZ29yaWVzOwogICAgICAgIGxldCB2aWRlb3MgPSBbXTsKICAgICAgICBmb3IgKGNvbnN0IGkgb2YgY2F0ZWdvcmllcykgewogICAgICAgICAgICB2aWRlb3MucHVzaCguLi50aGlzLmpzb24ydm9kcyhpLnZpZGVvcykpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uICh0aWQsIHBnLCBmaWx0ZXIsIGV4dGVuZCkgewogICAgICAgIGxldCB1cmwgPSBgJHt0aGlzLmhvc3R9L2FwaS5waHAvZmlsdGVyL3ZvZD90eXBlX25hbWU9JHtlbmNvZGVVUklDb21wb25lbnQodGlkKX0mcGFnZT0ke3BnfSZzb3J0PWhpdHNgOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgdmlkZW9zID0gdGhpcy5qc29uMnZvZHMoanNvbi5kYXRhKTsKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdm9kSWQgPSB0aGlzLmlucHV0Lm1hdGNoKC92b2RfaWQ9KFxkKykvKVsxXTsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9hcGkucGhwL3ZvZC9nZXRfZGV0YWlsP3ZvZF9pZD0ke3ZvZElkfWA7CiAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2godXJsLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzcC50ZXh0KCkpOwogICAgICAgIGxldCBkYXRhID0ganNvbi5kYXRhWzBdOwogICAgICAgIGxldCB2b2RwbGF5ZXIgPSBqc29uLnZvZHBsYXllcjsKICAgICAgICBsZXQgc2hvd3MgPSBbXTsKICAgICAgICBsZXQgcGxheV91cmxzID0gW107CiAgICAgICAgbGV0IHJhd19zaG93cyA9IGRhdGEudm9kX3BsYXlfZnJvbS5zcGxpdCgnJCQkJyk7CiAgICAgICAgbGV0IHJhd191cmxzX2xpc3QgPSBkYXRhLnZvZF9wbGF5X3VybC5zcGxpdCgnJCQkJyk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYXdfc2hvd3MubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgbGV0IHNob3dfY29kZSA9IHJhd19zaG93c1tpXTsKICAgICAgICAgICAgbGV0IHVybHNfc3RyID0gcmF3X3VybHNfbGlzdFtpXTsKICAgICAgICAgICAgbGV0IG5lZWRfcGFyc2UgPSAwOwogICAgICAgICAgICBsZXQgaXNfc2hvdyA9IDA7CiAgICAgICAgICAgIGxldCBuYW1lID0gc2hvd19jb2RlOwogICAgICAgICAgICBmb3IgKGNvbnN0IHBsYXllciBvZiB2b2RwbGF5ZXIpIHsKICAgICAgICAgICAgICAgIGlmIChwbGF5ZXIuZnJvbSA9PT0gc2hvd19jb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaXNfc2hvdyA9IDE7CiAgICAgICAgICAgICAgICAgICAgbmVlZF9wYXJzZSA9IHBsYXllci5kZWNvZGVfc3RhdHVzOwogICAgICAgICAgICAgICAgICAgIGlmIChzaG93X2NvZGUudG9Mb3dlckNhc2UoKSAhPT0gcGxheWVyLnNob3cudG9Mb3dlckNhc2UoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gYCR7cGxheWVyLnNob3d9ICgke3Nob3dfY29kZX0pYDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChpc19zaG93ID09PSAxKSB7CiAgICAgICAgICAgICAgICBsZXQgdXJscyA9IFtdOwogICAgICAgICAgICAgICAgbGV0IGl0ZW1zID0gdXJsc19zdHIuc3BsaXQoJyMnKTsKICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykgewogICAgICAgICAgICAgICAgICAgIGlmIChpdGVtLmluY2x1ZGVzKCckJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBhcnRzID0gaXRlbS5zcGxpdCgnJCcpOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXBpc29kZSA9IHBhcnRzWzBdOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgbV91cmwgPSBwYXJ0c1sxXTsKICAgICAgICAgICAgICAgICAgICAgICAgdXJscy5wdXNoKGAke2VwaXNvZGV9JCR7c2hvd19jb2RlfUAke25lZWRfcGFyc2V9QCR7bV91cmx9YCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHVybHMubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgICAgIHBsYXlfdXJscy5wdXNoKHVybHMuam9pbignIycpKTsKICAgICAgICAgICAgICAgICAgICBzaG93cy5wdXNoKG5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGxldCBWT0QgPSB7CiAgICAgICAgICAgIHZvZF9pZDogZGF0YS52b2RfaWQudG9TdHJpbmcoKSwKICAgICAgICAgICAgdm9kX25hbWU6IGRhdGEudm9kX25hbWUsCiAgICAgICAgICAgIHZvZF9waWM6IGRhdGEudm9kX3BpYywKICAgICAgICAgICAgdm9kX3JlbWFya3M6IGRhdGEudm9kX3JlbWFya3MsCiAgICAgICAgICAgIHZvZF95ZWFyOiBkYXRhLnZvZF95ZWFyLAogICAgICAgICAgICB2b2RfYXJlYTogZGF0YS52b2RfYXJlYSwKICAgICAgICAgICAgdm9kX2FjdG9yOiBkYXRhLnZvZF9hY3RvciwKICAgICAgICAgICAgdm9kX2RpcmVjdG9yOiBkYXRhLnZvZF9kaXJlY3RvciwKICAgICAgICAgICAgdm9kX2NvbnRlbnQ6IGRhdGEudm9kX2NvbnRlbnQsCiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206IHNob3dzLmpvaW4oJyQkJCcpLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHBsYXlfdXJscy5qb2luKCckJCQnKSwKICAgICAgICAgICAgdHlwZV9uYW1lOiBkYXRhLnZvZF9jbGFzcwogICAgICAgIH07CiAgICAgICAgcmV0dXJuIFZPRDsKICAgIH0sCiAgICAKICAgIOaQnOe0ojogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCB1cmwgPSBgJHt0aGlzLmhvc3R9L2FwaS5waHAvc2VhcmNoL2luZGV4P3dkPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuS0VZKX0mcGFnZT0ke3RoaXMuTVlfUEFHRX0mbGltaXQ9MTVgOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgdmlkZW9zID0gdGhpcy5qc29uMnZvZHMoanNvbi5kYXRhKTsKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICBsYXp5OiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgbGV0IFtwbGF5X2Zyb20sIG5lZWRfcGFyc2UsIHJhd191cmxdID0gdGhpcy5pbnB1dC5zcGxpdCgnQCcpOwogICAgICAgIGxldCBqeCA9IDA7CiAgICAgICAgbGV0IGZpbmFsX3VybCA9ICcnOwogICAgICAgIGlmIChuZWVkX3BhcnNlID09PSAnMScpIHsKICAgICAgICAgICAgbGV0IGF1dGhfdG9rZW4gPSAnJzsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgbGV0IGFwaVVybCA9IGAke3RoaXMuaG9zdH0vYXBpLnBocC9kZWNvZGUvdXJsLz91cmw9JHtlbmNvZGVVUklDb21wb25lbnQocmF3X3VybCl9JnZvZEZyb209JHtwbGF5X2Zyb219JHthdXRoX3Rva2VufWA7CiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2goYXBpVXJsLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KTsKICAgICAgICAgICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCByZXNwLnRleHQoKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGpzb24uY29kZSA9PT0gMiAmJiBqc29uLmNoYWxsZW5nZSkgewogICAgICAgICAgICAgICAgICAgICAgICBsZXQgdG9rZW4gPSBldmFsKGpzb24uY2hhbGxlbmdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0aF90b2tlbiA9IGAmdG9rZW49JHt0b2tlbn1gOwogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbGV0IHBsYXlfdXJsID0ganNvbi5kYXRhOwogICAgICAgICAgICAgICAgICAgIGlmIChwbGF5X3VybCAmJiBwbGF5X3VybC5zdGFydHNXaXRoKCdodHRwJykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxfdXJsID0gcGxheV91cmw7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGlmICghZmluYWxfdXJsKSB7CiAgICAgICAgICAgIGZpbmFsX3VybCA9IHJhd191cmw7CiAgICAgICAgICAgIGlmICgvKD86d3d3XC5pcWl5aXx2XC5xcXx2XC55b3VrdXx3d3dcLm1ndHZ8d3d3XC5iaWxpYmlsaSlcLmNvbS8udGVzdChyYXdfdXJsKSkgewogICAgICAgICAgICAgICAganggPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHBhcnNlOiBqeCwKICAgICAgICAgICAgdXJsOiBmaW5hbF91cmwsCiAgICAgICAgICAgIGhlYWRlcjogeyAnVXNlci1BZ2VudCc6IHRoaXMuaGVhZGVyc1snVXNlci1BZ2VudCddIH0KICAgICAgICB9OwogICAgfQp9Ow== \ No newline at end of file diff --git "a/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" "b/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" index 22af9d45..7204c5db 100644 --- "a/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" +++ "b/spider/js/\346\242\250\345\233\255\350\241\214[\346\210\217].js" @@ -11,251 +11,4 @@ }) */ -var rule = { - 类型: '影视', - author: 'EylinSir', - title: '梨园行戏曲', - desc: '梨园行戏曲源', - host: 'https://fly.daoran.tv', - homeUrl: 'https://fly.daoran.tv', - url: '/API_ROP/search/album/screen', - searchUrl: '/API_ROP/search/album/list?keyword=**', - logo: 'https://img.znds.com//uploads/new/221222/9-2212221050561N.png', - searchable: 1, - quickSearch: 0, - filterable: 1, - timeout: 10000, - play_parse: true, - headers: { - 'md5': 'SkvyrWqK9QHTdCT12Rhxunjx+WwMTe9y4KwgeASFDhbYabRSPskR0Q==', - 'Content-Type': 'application/json; charset=UTF-8', - 'User-Agent': 'okhttp/3.12.10', - 'Host': 'fly.daoran.tv', - 'Connection': 'Keep-Alive' - }, - - request: async function (url, obj) { - obj = obj || {}; - let response = await _fetch(url, { - method: obj.method || 'POST', - headers: obj.headers || this.headers, - body: obj.data ? JSON.stringify(obj.data) : undefined - }); - return response.text(); - }, - - _format_img: function (img) { - if (!img) { - return ''; - } - if (!img.startsWith('http')) { - return `https://ottphoto.daoran.tv/HD/${img}`; - } - return img; - }, - - 预处理: async function () {}, - - class_parse: async function () { - let cate_list = [ - {"n": "全部", "v": ""}, - {"n": "黄梅戏", "v": "hmx"}, {"n": "京剧", "v": "jingju"}, {"n": "曲剧", "v": "quju"}, - {"n": "秦腔", "v": "qinq"}, {"n": "潮剧", "v": "chaoju"}, {"n": "沪剧", "v": "huju"}, - {"n": "昆曲", "v": "kunqu"}, {"n": "淮剧", "v": "huaiju"}, {"n": "婺剧", "v": "wuju"}, - {"n": "河南大鼓书", "v": "hndgs"}, {"n": "滇剧", "v": "dianju"}, {"n": "老年大学", "v": "WK"}, - {"n": "绍剧", "v": "shaojv"}, {"n": "曲艺晚会", "v": "else"}, {"n": "皮影戏", "v": "pyx"}, - {"n": "四平调", "v": "spd"}, {"n": "吕剧", "v": "lvjv"}, {"n": "柳琴戏", "v": "liuqx"}, - {"n": "莆仙戏", "v": "pxx"}, {"n": "宛梆", "v": "wb"}, {"n": "锡剧", "v": "xiju"}, - {"n": "大平调", "v": "dpd"}, {"n": "话剧", "v": "huaju"}, {"n": "西秦戏", "v": "xqx"}, - {"n": "川剧", "v": "chuanju"}, {"n": "赣剧", "v": "tagId"}, {"n": "太康道情", "v": "tkdq"}, - {"n": "闽剧", "v": "minju"}, {"n": "梅花大鼓", "v": "mhdg"}, {"n": "吉剧", "v": "jiju"}, - {"n": "白字戏", "v": "bzx"}, {"n": "豫剧", "v": "yuju"}, {"n": "越剧", "v": "yueju"}, - {"n": "评剧", "v": "pingju"}, {"n": "坠子", "v": "hnzz"}, {"n": "河北梆子", "v": "hbbz"}, - {"n": "粤剧", "v": "gddx"}, {"n": "二夹弦", "v": "ejx"}, {"n": "河南琴书", "v": "hnqs"}, - {"n": "戏曲", "v": "xq"}, {"n": "二人台", "v": "ERT"}, {"n": "越调", "v": "yued"}, - {"n": "乐腔", "v": "lq"}, {"n": "扬剧", "v": "yangju"}, {"n": "京韵大鼓", "v": "jydg"}, - {"n": "彩调", "v": "caidiao"}, {"n": "琼剧", "v": "qiongju"}, {"n": "蒲剧", "v": "pujv"}, - {"n": "西河大鼓", "v": "xhdg"}, {"n": "湘剧", "v": "xj"}, {"n": "麦田乡韾", "v": "mtxy"}, - {"n": "评书", "v": "pingshu"}, {"n": "庐剧", "v": "luju"}, {"n": "单弦", "v": "danxian"}, - {"n": "花鼓戏", "v": "huagx"}, {"n": "相声", "v": "xiang"}, {"n": "四股弦", "v": "sgx"}, - {"n": "保定老调", "v": "bdld"}, {"n": "晋剧", "v": "jinju"}, {"n": "其他", "v": "other"}, - {"n": "正字戏", "v": "zzx"}, {"n": "楚剧", "v": "chuju"} - ]; - - return { - class: [{ 'type_name': '戏曲片库', 'type_id': 'all' }], - filters: { - "all": [ - {"key": "sect", "name": "曲种", "value": cate_list}, - {"key": "area", "name": "资费", "value": [{"n": "全部", "v": "0"}, {"n": "免费", "v": "1"}, {"n": "VIP", "v": "2"}]}, - {"key": "sort", "name": "排序", "value": [{"n": "最热", "v": "hot"}, {"n": "最新", "v": "online"}]} - ] - } - }; - }, - - 推荐: async function () { - return await this.一级('all', 1, {}, {}); - }, - - 一级: async function (tid, pg, filter, extend) { - let url = `${this.host}/API_ROP/search/album/screen`; - let sect = extend?.sect || ''; - if (tid === 'all' && !sect) { - sect = ''; - } - - let payload = { - "cur": parseInt(pg), - "pageSize": 30, - "resType": 1, - "sect": sect, - "orderby": extend?.sort || 'hot', - "tagId": 0, - "userId": "92315ec6e58a45ba7f47fd143b3d7956", - "channel": "vivo", - "item": "y9", - "nodeCode": "001000", - "project": "lyhxcx" - }; - - let area = extend?.area || '0'; - if (area === '1' || area === '2') { - payload['free'] = parseInt(area); - } - - try { - let resp = await this.request(url, { data: payload }); - let json = JSON.parse(resp); - let data = json.pb || json.data || {}; - let vod_list = []; - for (let item of data.dataList || []) { - vod_list.push({ - title: item.name, - url: `${this.host}/API_ROP/album/res/list?albumCode=${item.code}`, - desc: (item.publishTime || '').split(' ')[0], - pic_url: this._format_img(item.imgsec), - vod_year: (item.publishTime || '').substring(0, 4) - }); - } - - return setResult(vod_list); - } catch (e) { - console.error(e); - return setResult([]); - } - }, - - 二级: async function () { - let albumCode = this.input.match(/albumCode=(.*?)(?:&|$)/)[1]; - let url = `${this.host}/API_ROP/album/res/list`; - - let payload = { - "albumCode": albumCode, - "cur": 1, - "pageSize": 500, - "userId": "92315ec6e58a45ba7f47fd143b3d7956", - "channel": "vivo", - "item": "y9", - "nodeCode": "001000", - "project": "lyhxcx" - }; - - try { - let resp = await this.request(url, { data: payload }); - let json = JSON.parse(resp); - let album = json.album || {}; - let tracks = json.pb?.dataList || []; - tracks.sort((a, b) => parseInt(a.sort || 0) - parseInt(b.sort || 0)); - let play_urls = []; - for (let t of tracks) { - if (t.code) { - play_urls.push(`${t.name.replace(/\$/g, '_')}$${t.code}`); - } - } - - let VOD = { - vod_id: albumCode, - vod_name: album.name || '未知', - vod_pic: this._format_img(album.imgsec), - type_name: "戏曲", - vod_year: album.publishTime || '', - vod_area: "中国", - vod_content: album.des || '暂无简介', - vod_play_from: "梨园行", - vod_play_url: play_urls.join('#') - }; - - return VOD; - } catch (e) { - console.error(e); - return {}; - } - }, - - 搜索: async function () { - let url = `${this.host}/API_ROP/search/album/list`; - let payload = { - "cur": parseInt(this.MY_PAGE), - "pageSize": 20, - "keyword": this.KEY, - "item": "y9", - "nodeCode": "001000", - "orderby": "hot", - "px": 2, - "sect": [], - "userId": "92315ec6e58a45ba7f47fd143b3d7956", - "project": "lyhxcx" - }; - - try { - let resp = await this.request(url, { data: payload }); - let json = JSON.parse(resp); - let data = json.pb || json.data || {}; - let vod_list = []; - for (let item of data.dataList || []) { - vod_list.push({ - title: item.name, - url: `${this.host}/API_ROP/album/res/list?albumCode=${item.code}`, - desc: (item.publishTime || ''), - pic_url: this._format_img(item.imgsec) - }); - } - return setResult(vod_list); - } catch (e) { - console.error(e); - return setResult([]); - } - }, - - lazy: async function () { - let resCode = this.input; - let url = `${this.host}/API_ROP/play/get/playurl`; - let payload = { - "resCode": resCode, - "item": "y9", - "mask": 0, - "nodeCode": "001000", - "project": "lyhxcx", - "px": 2, - "userId": "92315ec6e58a45ba7f47fd143b3d7956" - }; - - try { - let resp = await this.request(url, { data: payload }); - let json = JSON.parse(resp); - let play_url = json.playres?.playurl || ''; - return { - parse: 0, - url: play_url, - header: { 'User-Agent': this.headers['User-Agent'] } - }; - } catch (e) { - console.error(e); - return { - parse: 0, - url: '' - }; - } - } -}; \ No newline at end of file +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflvbHop4YnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfmoqjlm63ooYzmiI/mm7InLAogICAgZGVzYzogJ+aiqOWbreihjOaIj+absua6kCcsCiAgICBob3N0OiAnaHR0cHM6Ly9mbHkuZGFvcmFuLnR2JywKICAgIGhvbWVVcmw6ICdodHRwczovL2ZseS5kYW9yYW4udHYnLAogICAgdXJsOiAnL0FQSV9ST1Avc2VhcmNoL2FsYnVtL3NjcmVlbicsCiAgICBzZWFyY2hVcmw6ICcvQVBJX1JPUC9zZWFyY2gvYWxidW0vbGlzdD9rZXl3b3JkPSoqJywKICAgIGxvZ286ICdodHRwczovL2ltZy56bmRzLmNvbS8vdXBsb2Fkcy9uZXcvMjIxMjIyLzktMjIxMjIyMTA1MDU2MU4ucG5nJywKICAgIHNlYXJjaGFibGU6IDEsCiAgICBxdWlja1NlYXJjaDogMCwKICAgIGZpbHRlcmFibGU6IDEsCiAgICB0aW1lb3V0OiAxMDAwMCwKICAgIHBsYXlfcGFyc2U6IHRydWUsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgJ21kNSc6ICdTa3Z5cldxSzlRSFRkQ1QxMlJoeHVuangrV3dNVGU5eTRLd2dlQVNGRGhiWWFiUlNQc2tSMFE9PScsCiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04JywKICAgICAgICAnVXNlci1BZ2VudCc6ICdva2h0dHAvMy4xMi4xMCcsCiAgICAgICAgJ0hvc3QnOiAnZmx5LmRhb3Jhbi50dicsCiAgICAgICAgJ0Nvbm5lY3Rpb24nOiAnS2VlcC1BbGl2ZScKICAgIH0sCiAgICAKICAgIHJlcXVlc3Q6IGFzeW5jIGZ1bmN0aW9uICh1cmwsIG9iaikgewogICAgICAgIG9iaiA9IG9iaiB8fCB7fTsKICAgICAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBfZmV0Y2godXJsLCB7CiAgICAgICAgICAgIG1ldGhvZDogb2JqLm1ldGhvZCB8fCAnUE9TVCcsCiAgICAgICAgICAgIGhlYWRlcnM6IG9iai5oZWFkZXJzIHx8IHRoaXMuaGVhZGVycywKICAgICAgICAgICAgYm9keTogb2JqLmRhdGEgPyBKU09OLnN0cmluZ2lmeShvYmouZGF0YSkgOiB1bmRlZmluZWQKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpOwogICAgfSwKCiAgICBfZm9ybWF0X2ltZzogZnVuY3Rpb24gKGltZykgewogICAgICAgIGlmICghaW1nKSB7CiAgICAgICAgICAgIHJldHVybiAnJzsKICAgICAgICB9CiAgICAgICAgaWYgKCFpbWcuc3RhcnRzV2l0aCgnaHR0cCcpKSB7CiAgICAgICAgICAgIHJldHVybiBgaHR0cHM6Ly9vdHRwaG90by5kYW9yYW4udHYvSEQvJHtpbWd9YDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGltZzsKICAgIH0sCiAgICAKICAgIOmihOWkhOeQhjogYXN5bmMgZnVuY3Rpb24gKCkge30sCiAgICAKICAgIGNsYXNzX3BhcnNlOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgbGV0IGNhdGVfbGlzdCA9IFsKICAgICAgICAgICAgeyJuIjogIuWFqOmDqCIsICJ2IjogIiJ9LAogICAgICAgICAgICB7Im4iOiAi6buE5qKF5oiPIiwgInYiOiAiaG14In0sIHsibiI6ICLkuqzliaciLCAidiI6ICJqaW5nanUifSwgeyJuIjogIuabsuWJpyIsICJ2IjogInF1anUifSwKICAgICAgICAgICAgeyJuIjogIuenpuiFlCIsICJ2IjogInFpbnEifSwgeyJuIjogIua9ruWJpyIsICJ2IjogImNoYW9qdSJ9LCB7Im4iOiAi5rKq5YmnIiwgInYiOiAiaHVqdSJ9LAogICAgICAgICAgICB7Im4iOiAi5piG5puyIiwgInYiOiAia3VucXUifSwgeyJuIjogIua3ruWJpyIsICJ2IjogImh1YWlqdSJ9LCB7Im4iOiAi5am65YmnIiwgInYiOiAid3VqdSJ9LAogICAgICAgICAgICB7Im4iOiAi5rKz5Y2X5aSn6byT5LmmIiwgInYiOiAiaG5kZ3MifSwgeyJuIjogIua7h+WJpyIsICJ2IjogImRpYW5qdSJ9LCB7Im4iOiAi6ICB5bm05aSn5a2mIiwgInYiOiAiV0sifSwKICAgICAgICAgICAgeyJuIjogIue7jeWJpyIsICJ2IjogInNoYW9qdiJ9LCB7Im4iOiAi5puy6Im65pma5LyaIiwgInYiOiAiZWxzZSJ9LCB7Im4iOiAi55qu5b2x5oiPIiwgInYiOiAicHl4In0sCiAgICAgICAgICAgIHsibiI6ICLlm5vlubPosIMiLCAidiI6ICJzcGQifSwgeyJuIjogIuWQleWJpyIsICJ2IjogImx2anYifSwgeyJuIjogIuafs+eQtOaIjyIsICJ2IjogImxpdXF4In0sCiAgICAgICAgICAgIHsibiI6ICLojobku5nmiI8iLCAidiI6ICJweHgifSwgeyJuIjogIuWum+aihiIsICJ2IjogIndiIn0sIHsibiI6ICLplKHliaciLCAidiI6ICJ4aWp1In0sCiAgICAgICAgICAgIHsibiI6ICLlpKflubPosIMiLCAidiI6ICJkcGQifSwgeyJuIjogIuivneWJpyIsICJ2IjogImh1YWp1In0sIHsibiI6ICLopb/np6bmiI8iLCAidiI6ICJ4cXgifSwKICAgICAgICAgICAgeyJuIjogIuW3neWJpyIsICJ2IjogImNodWFuanUifSwgeyJuIjogIui1o+WJpyIsICJ2IjogInRhZ0lkIn0sIHsibiI6ICLlpKrlurfpgZPmg4UiLCAidiI6ICJ0a2RxIn0sCiAgICAgICAgICAgIHsibiI6ICLpl73liaciLCAidiI6ICJtaW5qdSJ9LCB7Im4iOiAi5qKF6Iqx5aSn6byTIiwgInYiOiAibWhkZyJ9LCB7Im4iOiAi5ZCJ5YmnIiwgInYiOiAiamlqdSJ9LAogICAgICAgICAgICB7Im4iOiAi55m95a2X5oiPIiwgInYiOiAiYnp4In0sIHsibiI6ICLosavliaciLCAidiI6ICJ5dWp1In0sIHsibiI6ICLotorliaciLCAidiI6ICJ5dWVqdSJ9LAogICAgICAgICAgICB7Im4iOiAi6K+E5YmnIiwgInYiOiAicGluZ2p1In0sIHsibiI6ICLlnaDlrZAiLCAidiI6ICJobnp6In0sIHsibiI6ICLmsrPljJfmooblrZAiLCAidiI6ICJoYmJ6In0sCiAgICAgICAgICAgIHsibiI6ICLnsqTliaciLCAidiI6ICJnZGR4In0sIHsibiI6ICLkuozlpLnlvKYiLCAidiI6ICJlangifSwgeyJuIjogIuays+WNl+eQtOS5piIsICJ2IjogImhucXMifSwKICAgICAgICAgICAgeyJuIjogIuaIj+absiIsICJ2IjogInhxIn0sIHsibiI6ICLkuozkurrlj7AiLCAidiI6ICJFUlQifSwgeyJuIjogIui2iuiwgyIsICJ2IjogInl1ZWQifSwKICAgICAgICAgICAgeyJuIjogIuS5kOiFlCIsICJ2IjogImxxIn0sIHsibiI6ICLmiazliaciLCAidiI6ICJ5YW5nanUifSwgeyJuIjogIuS6rOmfteWkp+m8kyIsICJ2IjogImp5ZGcifSwKICAgICAgICAgICAgeyJuIjogIuW9qeiwgyIsICJ2IjogImNhaWRpYW8ifSwgeyJuIjogIueQvOWJpyIsICJ2IjogInFpb25nanUifSwgeyJuIjogIuiSsuWJpyIsICJ2IjogInB1anYifSwKICAgICAgICAgICAgeyJuIjogIuilv+ays+Wkp+m8kyIsICJ2IjogInhoZGcifSwgeyJuIjogIua5mOWJpyIsICJ2IjogInhqIn0sIHsibiI6ICLpuqbnlLDkuaHpn74iLCAidiI6ICJtdHh5In0sCiAgICAgICAgICAgIHsibiI6ICLor4TkuaYiLCAidiI6ICJwaW5nc2h1In0sIHsibiI6ICLlupDliaciLCAidiI6ICJsdWp1In0sIHsibiI6ICLljZXlvKYiLCAidiI6ICJkYW54aWFuIn0sCiAgICAgICAgICAgIHsibiI6ICLoirHpvJPmiI8iLCAidiI6ICJodWFneCJ9LCB7Im4iOiAi55u45aOwIiwgInYiOiAieGlhbmcifSwgeyJuIjogIuWbm+iCoeW8piIsICJ2IjogInNneCJ9LAogICAgICAgICAgICB7Im4iOiAi5L+d5a6a6ICB6LCDIiwgInYiOiAiYmRsZCJ9LCB7Im4iOiAi5pmL5YmnIiwgInYiOiAiamluanUifSwgeyJuIjogIuWFtuS7liIsICJ2IjogIm90aGVyIn0sCiAgICAgICAgICAgIHsibiI6ICLmraPlrZfmiI8iLCAidiI6ICJ6engifSwgeyJuIjogIualmuWJpyIsICJ2IjogImNodWp1In0KICAgICAgICBdOwogICAgICAgIAogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGNsYXNzOiBbeyAndHlwZV9uYW1lJzogJ+aIj+absueJh+W6kycsICd0eXBlX2lkJzogJ2FsbCcgfV0sCiAgICAgICAgICAgIGZpbHRlcnM6IHsKICAgICAgICAgICAgICAgICJhbGwiOiBbCiAgICAgICAgICAgICAgICAgICAgeyJrZXkiOiAic2VjdCIsICJuYW1lIjogIuabsuenjSIsICJ2YWx1ZSI6IGNhdGVfbGlzdH0sCiAgICAgICAgICAgICAgICAgICAgeyJrZXkiOiAiYXJlYSIsICJuYW1lIjogIui1hOi0uSIsICJ2YWx1ZSI6IFt7Im4iOiAi5YWo6YOoIiwgInYiOiAiMCJ9LCB7Im4iOiAi5YWN6LS5IiwgInYiOiAiMSJ9LCB7Im4iOiAiVklQIiwgInYiOiAiMiJ9XX0sCiAgICAgICAgICAgICAgICAgICAgeyJrZXkiOiAic29ydCIsICJuYW1lIjogIuaOkuW6jyIsICJ2YWx1ZSI6IFt7Im4iOiAi5pyA54OtIiwgInYiOiAiaG90In0sIHsibiI6ICLmnIDmlrAiLCAidiI6ICJvbmxpbmUifV19CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfSwKICAgIAogICAg5o6o6I2QOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMu5LiA57qnKCdhbGwnLCAxLCB7fSwge30pOwogICAgfSwKICAgIAogICAg5LiA57qnOiBhc3luYyBmdW5jdGlvbiAodGlkLCBwZywgZmlsdGVyLCBleHRlbmQpIHsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9BUElfUk9QL3NlYXJjaC9hbGJ1bS9zY3JlZW5gOwogICAgICAgIGxldCBzZWN0ID0gZXh0ZW5kPy5zZWN0IHx8ICcnOwogICAgICAgIGlmICh0aWQgPT09ICdhbGwnICYmICFzZWN0KSB7CiAgICAgICAgICAgIHNlY3QgPSAnJzsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgbGV0IHBheWxvYWQgPSB7CiAgICAgICAgICAgICJjdXIiOiBwYXJzZUludChwZyksCiAgICAgICAgICAgICJwYWdlU2l6ZSI6IDMwLAogICAgICAgICAgICAicmVzVHlwZSI6IDEsCiAgICAgICAgICAgICJzZWN0Ijogc2VjdCwKICAgICAgICAgICAgIm9yZGVyYnkiOiBleHRlbmQ/LnNvcnQgfHwgJ2hvdCcsCiAgICAgICAgICAgICJ0YWdJZCI6IDAsCiAgICAgICAgICAgICJ1c2VySWQiOiAiOTIzMTVlYzZlNThhNDViYTdmNDdmZDE0M2IzZDc5NTYiLAogICAgICAgICAgICAiY2hhbm5lbCI6ICJ2aXZvIiwKICAgICAgICAgICAgIml0ZW0iOiAieTkiLAogICAgICAgICAgICAibm9kZUNvZGUiOiAiMDAxMDAwIiwKICAgICAgICAgICAgInByb2plY3QiOiAibHloeGN4IgogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgbGV0IGFyZWEgPSBleHRlbmQ/LmFyZWEgfHwgJzAnOwogICAgICAgIGlmIChhcmVhID09PSAnMScgfHwgYXJlYSA9PT0gJzInKSB7CiAgICAgICAgICAgIHBheWxvYWRbJ2ZyZWUnXSA9IHBhcnNlSW50KGFyZWEpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICB0cnkgewogICAgICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IHRoaXMucmVxdWVzdCh1cmwsIHsgZGF0YTogcGF5bG9hZCB9KTsKICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKHJlc3ApOwogICAgICAgICAgICBsZXQgZGF0YSA9IGpzb24ucGIgfHwganNvbi5kYXRhIHx8IHt9OwogICAgICAgICAgICBsZXQgdm9kX2xpc3QgPSBbXTsKICAgICAgICAgICAgZm9yIChsZXQgaXRlbSBvZiBkYXRhLmRhdGFMaXN0IHx8IFtdKSB7CiAgICAgICAgICAgICAgICB2b2RfbGlzdC5wdXNoKHsKICAgICAgICAgICAgICAgICAgICB0aXRsZTogaXRlbS5uYW1lLAogICAgICAgICAgICAgICAgICAgIHVybDogYCR7dGhpcy5ob3N0fS9BUElfUk9QL2FsYnVtL3Jlcy9saXN0P2FsYnVtQ29kZT0ke2l0ZW0uY29kZX1gLAogICAgICAgICAgICAgICAgICAgIGRlc2M6IChpdGVtLnB1Ymxpc2hUaW1lIHx8ICcnKS5zcGxpdCgnICcpWzBdLAogICAgICAgICAgICAgICAgICAgIHBpY191cmw6IHRoaXMuX2Zvcm1hdF9pbWcoaXRlbS5pbWdzZWMpLAogICAgICAgICAgICAgICAgICAgIHZvZF95ZWFyOiAoaXRlbS5wdWJsaXNoVGltZSB8fCAnJykuc3Vic3RyaW5nKDAsIDQpCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIHNldFJlc3VsdCh2b2RfbGlzdCk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpOwogICAgICAgICAgICByZXR1cm4gc2V0UmVzdWx0KFtdKTsKICAgICAgICB9CiAgICB9LAogICAgCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgYWxidW1Db2RlID0gdGhpcy5pbnB1dC5tYXRjaCgvYWxidW1Db2RlPSguKj8pKD86JnwkKS8pWzFdOwogICAgICAgIGxldCB1cmwgPSBgJHt0aGlzLmhvc3R9L0FQSV9ST1AvYWxidW0vcmVzL2xpc3RgOwogICAgICAgIAogICAgICAgIGxldCBwYXlsb2FkID0gewogICAgICAgICAgICAiYWxidW1Db2RlIjogYWxidW1Db2RlLAogICAgICAgICAgICAiY3VyIjogMSwKICAgICAgICAgICAgInBhZ2VTaXplIjogNTAwLAogICAgICAgICAgICAidXNlcklkIjogIjkyMzE1ZWM2ZTU4YTQ1YmE3ZjQ3ZmQxNDNiM2Q3OTU2IiwKICAgICAgICAgICAgImNoYW5uZWwiOiAidml2byIsCiAgICAgICAgICAgICJpdGVtIjogInk5IiwKICAgICAgICAgICAgIm5vZGVDb2RlIjogIjAwMTAwMCIsCiAgICAgICAgICAgICJwcm9qZWN0IjogImx5aHhjeCIKICAgICAgICB9OwogICAgICAgIAogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCByZXNwID0gYXdhaXQgdGhpcy5yZXF1ZXN0KHVybCwgeyBkYXRhOiBwYXlsb2FkIH0pOwogICAgICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UocmVzcCk7CiAgICAgICAgICAgIGxldCBhbGJ1bSA9IGpzb24uYWxidW0gfHwge307CiAgICAgICAgICAgIGxldCB0cmFja3MgPSBqc29uLnBiPy5kYXRhTGlzdCB8fCBbXTsKICAgICAgICAgICAgdHJhY2tzLnNvcnQoKGEsIGIpID0+IHBhcnNlSW50KGEuc29ydCB8fCAwKSAtIHBhcnNlSW50KGIuc29ydCB8fCAwKSk7CiAgICAgICAgICAgIGxldCBwbGF5X3VybHMgPSBbXTsKICAgICAgICAgICAgZm9yIChsZXQgdCBvZiB0cmFja3MpIHsKICAgICAgICAgICAgICAgIGlmICh0LmNvZGUpIHsKICAgICAgICAgICAgICAgICAgICBwbGF5X3VybHMucHVzaChgJHt0Lm5hbWUucmVwbGFjZSgvXCQvZywgJ18nKX0kJHt0LmNvZGV9YCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIGxldCBWT0QgPSB7CiAgICAgICAgICAgICAgICB2b2RfaWQ6IGFsYnVtQ29kZSwKICAgICAgICAgICAgICAgIHZvZF9uYW1lOiBhbGJ1bS5uYW1lIHx8ICfmnKrnn6UnLAogICAgICAgICAgICAgICAgdm9kX3BpYzogdGhpcy5fZm9ybWF0X2ltZyhhbGJ1bS5pbWdzZWMpLAogICAgICAgICAgICAgICAgdHlwZV9uYW1lOiAi5oiP5puyIiwKICAgICAgICAgICAgICAgIHZvZF95ZWFyOiBhbGJ1bS5wdWJsaXNoVGltZSB8fCAnJywKICAgICAgICAgICAgICAgIHZvZF9hcmVhOiAi5Lit5Zu9IiwKICAgICAgICAgICAgICAgIHZvZF9jb250ZW50OiBhbGJ1bS5kZXMgfHwgJ+aaguaXoOeugOS7iycsCiAgICAgICAgICAgICAgICB2b2RfcGxheV9mcm9tOiAi5qKo5Zut6KGMIiwKICAgICAgICAgICAgICAgIHZvZF9wbGF5X3VybDogcGxheV91cmxzLmpvaW4oJyMnKQogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIFZPRDsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7CiAgICAgICAgICAgIHJldHVybiB7fTsKICAgICAgICB9CiAgICB9LAogICAgCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9BUElfUk9QL3NlYXJjaC9hbGJ1bS9saXN0YDsKICAgICAgICBsZXQgcGF5bG9hZCA9IHsKICAgICAgICAgICAgImN1ciI6IHBhcnNlSW50KHRoaXMuTVlfUEFHRSksCiAgICAgICAgICAgICJwYWdlU2l6ZSI6IDIwLAogICAgICAgICAgICAia2V5d29yZCI6IHRoaXMuS0VZLAogICAgICAgICAgICAiaXRlbSI6ICJ5OSIsCiAgICAgICAgICAgICJub2RlQ29kZSI6ICIwMDEwMDAiLAogICAgICAgICAgICAib3JkZXJieSI6ICJob3QiLAogICAgICAgICAgICAicHgiOiAyLAogICAgICAgICAgICAic2VjdCI6IFtdLAogICAgICAgICAgICAidXNlcklkIjogIjkyMzE1ZWM2ZTU4YTQ1YmE3ZjQ3ZmQxNDNiM2Q3OTU2IiwKICAgICAgICAgICAgInByb2plY3QiOiAibHloeGN4IgogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCB0aGlzLnJlcXVlc3QodXJsLCB7IGRhdGE6IHBheWxvYWQgfSk7CiAgICAgICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShyZXNwKTsKICAgICAgICAgICAgbGV0IGRhdGEgPSBqc29uLnBiIHx8IGpzb24uZGF0YSB8fCB7fTsKICAgICAgICAgICAgbGV0IHZvZF9saXN0ID0gW107CiAgICAgICAgICAgIGZvciAobGV0IGl0ZW0gb2YgZGF0YS5kYXRhTGlzdCB8fCBbXSkgewogICAgICAgICAgICAgICAgdm9kX2xpc3QucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGl0ZW0ubmFtZSwKICAgICAgICAgICAgICAgICAgICB1cmw6IGAke3RoaXMuaG9zdH0vQVBJX1JPUC9hbGJ1bS9yZXMvbGlzdD9hbGJ1bUNvZGU9JHtpdGVtLmNvZGV9YCwKICAgICAgICAgICAgICAgICAgICBkZXNjOiAoaXRlbS5wdWJsaXNoVGltZSB8fCAnJyksCiAgICAgICAgICAgICAgICAgICAgcGljX3VybDogdGhpcy5fZm9ybWF0X2ltZyhpdGVtLmltZ3NlYykKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBzZXRSZXN1bHQodm9kX2xpc3QpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTsKICAgICAgICAgICAgcmV0dXJuIHNldFJlc3VsdChbXSk7CiAgICAgICAgfQogICAgfSwKICAgIAogICAgbGF6eTogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCByZXNDb2RlID0gdGhpcy5pbnB1dDsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9BUElfUk9QL3BsYXkvZ2V0L3BsYXl1cmxgOwogICAgICAgIGxldCBwYXlsb2FkID0gewogICAgICAgICAgICAicmVzQ29kZSI6IHJlc0NvZGUsCiAgICAgICAgICAgICJpdGVtIjogInk5IiwKICAgICAgICAgICAgIm1hc2siOiAwLAogICAgICAgICAgICAibm9kZUNvZGUiOiAiMDAxMDAwIiwKICAgICAgICAgICAgInByb2plY3QiOiAibHloeGN4IiwKICAgICAgICAgICAgInB4IjogMiwKICAgICAgICAgICAgInVzZXJJZCI6ICI5MjMxNWVjNmU1OGE0NWJhN2Y0N2ZkMTQzYjNkNzk1NiIKICAgICAgICB9OwogICAgICAgIAogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCByZXNwID0gYXdhaXQgdGhpcy5yZXF1ZXN0KHVybCwgeyBkYXRhOiBwYXlsb2FkIH0pOwogICAgICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UocmVzcCk7CiAgICAgICAgICAgIGxldCBwbGF5X3VybCA9IGpzb24ucGxheXJlcz8ucGxheXVybCB8fCAnJzsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIHBhcnNlOiAwLAogICAgICAgICAgICAgICAgdXJsOiBwbGF5X3VybCwKICAgICAgICAgICAgICAgIGhlYWRlcjogeyAnVXNlci1BZ2VudCc6IHRoaXMuaGVhZGVyc1snVXNlci1BZ2VudCddIH0KICAgICAgICAgICAgfTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBwYXJzZTogMCwKICAgICAgICAgICAgICAgIHVybDogJycKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn07 \ No newline at end of file diff --git "a/spider/js/\347\203\255\346\222\255\345\275\261\350\247\206.js" "b/spider/js/\347\203\255\346\222\255\345\275\261\350\247\206.js" new file mode 100644 index 00000000..4ffd935a --- /dev/null +++ "b/spider/js/\347\203\255\346\222\255\345\275\261\350\247\206.js" @@ -0,0 +1,13 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '热播APP', + author: 'EylinSir', + '类型': '影视', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflvbHop4YnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfng63mkq1BUFAnLAogICAgZGVzYzogJ+eDreaSrUFQUOW9seinhua6kCcsCiAgICBob3N0OiAnaHR0cDovL3YucmJvdHYuY24nLAogICAgaG9tZVVybDogJ2h0dHA6Ly92LnJib3R2LmNuJywKICAgIHVybDogJy92My9ob21lL3R5cGVfc2VhcmNoJywKICAgIHNlYXJjaFVybDogJy92My9ob21lL3NlYXJjaCcsCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDEsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgdGltZW91dDogMTAwMDAsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAgaGVhZGVyczogewogICAgICAgICdVc2VyLUFnZW50JzogJ29raHR0cC1va2dvL2plYXNvbmx6eScsCiAgICAgICAgJ0FjY2VwdC1MYW5ndWFnZSc6ICd6aC1DTix6aDtxPTAuOCcKICAgIH0sCiAgICAKICAgIGdldGZpbGVzOiBmdW5jdGlvbiAocCA9IHt9KSB7CiAgICAgICAgbGV0IHQgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKS50b1N0cmluZygpOwogICAgICAgIGxldCBzID0gbWQ1KCc3Z3AwYm5kMnNyODV5ZGlpMmozMnBjeXBzY29jNHc2YzdnNXNwbCcgKyB0KTsKICAgICAgICBsZXQgZmlsZXMgPSB7CiAgICAgICAgICAgICdzaWduJzogcywKICAgICAgICAgICAgJ3RpbWVzdGFtcCc6IHQKICAgICAgICB9OwogICAgICAgIHJldHVybiB7IC4uLnAsIC4uLmZpbGVzIH07CiAgICB9LAoKICAgIGdldHY6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgcmV0dXJuIGRhdGEuZmlsdGVyKGkgPT4gaS52b2RfaWQgJiYgaS52b2RfaWQudG9TdHJpbmcoKSAhPT0gJzAnKS5tYXAoaSA9PiAoewogICAgICAgICAgICB0aXRsZTogaS52b2RfbmFtZSwKICAgICAgICAgICAgdXJsOiBgJHt0aGlzLmhvc3R9L3YzL2hvbWUvdm9kX2RldGFpbHM/dm9kX2lkPSR7aS52b2RfaWR9YCwKICAgICAgICAgICAgZGVzYzogaS52b2RfcmVtYXJrcywKICAgICAgICAgICAgcGljX3VybDogaS52b2RfcGljIHx8IGkudm9kX3BpY190aHVtYiwKICAgICAgICAgICAgdm9kX3llYXI6IGkudGFnCiAgICAgICAgfSkpOwogICAgfSwKICAgIAogICAg6aKE5aSE55CGOiBhc3luYyBmdW5jdGlvbiAoKSB7fSwKCiAgICBjbGFzc19wYXJzZTogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBkYXRhID0gdGhpcy5nZXRmaWxlcyh7ICcnOiAnJyB9KTsKICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3YzL3R5cGUvdG9wX3R5cGVgLCB7CiAgICAgICAgICAgIG1ldGhvZDogJ3Bvc3QnLAogICAgICAgICAgICBoZWFkZXJzOiB7IC4uLnRoaXMuaGVhZGVycywgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnIH0sCiAgICAgICAgICAgIGJvZHk6IG5ldyBVUkxTZWFyY2hQYXJhbXMoZGF0YSkudG9TdHJpbmcoKQogICAgICAgIH0pOwogICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShhd2FpdCByZXNwLnRleHQoKSk7CiAgICAgICAgbGV0IGNsYXNzZXMgPSBqc29uLmRhdGEubGlzdC5tYXAoayA9PiAoewogICAgICAgICAgICB0eXBlX2lkOiBrLnR5cGVfaWQudG9TdHJpbmcoKSwKICAgICAgICAgICAgdHlwZV9uYW1lOiBrLnR5cGVfbmFtZQogICAgICAgIH0pKTsKICAgICAgICBsZXQgZmlsdGVycyA9IHt9OwogICAgICAgIGZvciAoY29uc3QgayBvZiBqc29uLmRhdGEubGlzdCkgewogICAgICAgICAgICBsZXQgZnRzID0gW107CiAgICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGspKSB7CiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID4gMikgewogICAgICAgICAgICAgICAgICAgIGZ0cy5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZToga2V5LAogICAgICAgICAgICAgICAgICAgICAgICBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS5maWx0ZXIoaiA9PiBqICYmIGogIT09ICflhajpg6gnKS5tYXAoaiA9PiAoeyBuOiBqLCB2OiBqIH0pKQogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChmdHMubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBmaWx0ZXJzW2sudHlwZV9pZF0gPSBmdHM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgY2xhc3M6IGNsYXNzZXMsIGZpbHRlcnMgfTsKICAgIH0sCiAgICAKICAgIOaOqOiNkDogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBkYXRhID0gdGhpcy5nZXRmaWxlcyh7ICcnOiAnJyB9KTsKICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3YzL3R5cGUvdGpfdm9kYCwgewogICAgICAgICAgICBtZXRob2Q6ICdwb3N0JywKICAgICAgICAgICAgaGVhZGVyczogeyAuLi50aGlzLmhlYWRlcnMsICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LAogICAgICAgICAgICBib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKGRhdGEpLnRvU3RyaW5nKCkKICAgICAgICB9KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzcC50ZXh0KCkpOwogICAgICAgIGxldCB2aWRlb3MgPSB0aGlzLmdldHYoanNvbi5kYXRhLmNhaS5jb25jYXQoanNvbi5kYXRhLmxvb3ApKTsKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uICh0aWQsIHBnLCBmaWx0ZXIsIGV4dGVuZCkgewogICAgICAgIGxldCBmaWxlcyA9IHsKICAgICAgICAgICAgJ3R5cGVfaWQnOiB0aWQsCiAgICAgICAgICAgICdsaW1pdCc6ICcxMicsCiAgICAgICAgICAgICdwYWdlJzogcGcKICAgICAgICB9OwogICAgICAgIGZvciAoY29uc3QgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKGV4dGVuZCB8fCB7fSkpIHsKICAgICAgICAgICAgbGV0IGtleSA9IGsgPT09ICdleHRlbmQnID8gJ2NsYXNzJyA6IGs7CiAgICAgICAgICAgIGZpbGVzW2tleV0gPSB2OwogICAgICAgIH0KICAgICAgICBsZXQgZGF0YSA9IHRoaXMuZ2V0ZmlsZXMoZmlsZXMpOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKGAke3RoaXMuaG9zdH0vdjMvaG9tZS90eXBlX3NlYXJjaGAsIHsKICAgICAgICAgICAgbWV0aG9kOiAncG9zdCcsCiAgICAgICAgICAgIGhlYWRlcnM6IHsgLi4udGhpcy5oZWFkZXJzLCAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcgfSwKICAgICAgICAgICAgYm9keTogbmV3IFVSTFNlYXJjaFBhcmFtcyhkYXRhKS50b1N0cmluZygpCiAgICAgICAgfSk7CiAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IHJlc3AudGV4dCgpKTsKICAgICAgICBsZXQgdmlkZW9zID0gdGhpcy5nZXR2KGpzb24uZGF0YS5saXN0KTsKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgdm9kSWQgPSB0aGlzLmlucHV0Lm1hdGNoKC92b2RfaWQ9KFxkKykvKVsxXTsKICAgICAgICBsZXQgZGF0YSA9IHRoaXMuZ2V0ZmlsZXMoeyAndm9kX2lkJzogdm9kSWQgfSk7CiAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2goYCR7dGhpcy5ob3N0fS92My9ob21lL3ZvZF9kZXRhaWxzYCwgewogICAgICAgICAgICBtZXRob2Q6ICdwb3N0JywKICAgICAgICAgICAgaGVhZGVyczogeyAuLi50aGlzLmhlYWRlcnMsICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LAogICAgICAgICAgICBib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKGRhdGEpLnRvU3RyaW5nKCkKICAgICAgICB9KTsKICAgICAgICBsZXQgdiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzcC50ZXh0KCkpLmRhdGE7CiAgICAgICAgbGV0IFZPRCA9IHsKICAgICAgICAgICAgdm9kX2lkOiB2LnZvZF9pZC50b1N0cmluZygpLAogICAgICAgICAgICB2b2RfbmFtZTogdi52b2RfbmFtZSwKICAgICAgICAgICAgdHlwZV9uYW1lOiB2LnR5cGVfbmFtZSwKICAgICAgICAgICAgdm9kX3llYXI6IHYudm9kX3llYXIsCiAgICAgICAgICAgIHZvZF9hcmVhOiB2LnZvZF9hcmVhLAogICAgICAgICAgICB2b2RfcmVtYXJrczogdi52b2RfcmVtYXJrcywKICAgICAgICAgICAgdm9kX2FjdG9yOiB2LnZvZF9hY3RvciwKICAgICAgICAgICAgdm9kX2RpcmVjdG9yOiB2LnZvZF9kaXJlY3RvciwKICAgICAgICAgICAgdm9kX2NvbnRlbnQ6ICh2LnZvZF9jb250ZW50IHx8ICfml6AnKS5yZXBsYWNlKC88W14+XSo+L2csICcnKS50cmltKCkKICAgICAgICB9OwogICAgICAgIGxldCBuID0gW107CiAgICAgICAgbGV0IHAgPSBbXTsKICAgICAgICBmb3IgKGNvbnN0IGkgb2Ygdi52b2RfcGxheV9saXN0KSB7CiAgICAgICAgICAgIGxldCBwYXJzZXMgPSBpLnBhcnNlX3VybHMuam9pbignLCcpOwogICAgICAgICAgICBsZXQgdXJscyA9IGkudXJscy5tYXAoaiA9PiBgJHtqLm5hbWV9JCR7ai51cmx9QCR7cGFyc2VzfUAke2kudWEgfHwgJyd9QCR7aS5yZWZlcmVyIHx8ICcnfWApOwogICAgICAgICAgICBwLnB1c2godXJscy5qb2luKCcjJykpOwogICAgICAgICAgICBsZXQgbmFtZSA9IChpLnRpdGxlIHx8IGkubmFtZSB8fCAnJykucmVwbGFjZSgvW1wo77yIXSg/OueCueWHu3zmjaIpW14pXSpbXCnvvIldfFta4pa24p2k44CQXS4qL2csICcnKTsKICAgICAgICAgICAgbi5wdXNoKG5hbWUgPT09IGkuZmxhZyA/IG5hbWUgOiBgJHtuYW1lfSgke2kuZmxhZ30pYCk7CiAgICAgICAgfQogICAgICAgIFZPRC52b2RfcGxheV9mcm9tID0gbi5qb2luKCckJCQnKTsKICAgICAgICBWT0Qudm9kX3BsYXlfdXJsID0gcC5qb2luKCckJCQnKTsKICAgICAgICByZXR1cm4gVk9EOwogICAgfSwKICAgIAogICAg5pCc57SiOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgbGV0IGZpbGVzID0gewogICAgICAgICAgICAnbGltaXQnOiAnMTInLAogICAgICAgICAgICAncGFnZSc6IHRoaXMuTVlfUEFHRSwKICAgICAgICAgICAgJ2tleXdvcmQnOiB0aGlzLktFWQogICAgICAgIH07CiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmdldGZpbGVzKGZpbGVzKTsKICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3YzL2hvbWUvc2VhcmNoYCwgewogICAgICAgICAgICBtZXRob2Q6ICdwb3N0JywKICAgICAgICAgICAgaGVhZGVyczogeyAuLi50aGlzLmhlYWRlcnMsICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyB9LAogICAgICAgICAgICBib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKGRhdGEpLnRvU3RyaW5nKCkKICAgICAgICB9KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzcC50ZXh0KCkpOwogICAgICAgIGxldCB2aWRlb3MgPSB0aGlzLmdldHYoanNvbi5kYXRhLmxpc3QpOwogICAgICAgIHJldHVybiBzZXRSZXN1bHQodmlkZW9zKTsKICAgIH0sCiAgICAKICAgIGxhenk6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgW3Jhd191cmwsIHBhcnNlc1N0ciA9ICcnLCB1YSA9ICcnLCByZWZlcmVyID0gJyddID0gdGhpcy5pbnB1dC5zcGxpdCgnQCcpOwogICAgICAgIGxldCBwYXJzZXMgPSBwYXJzZXNTdHIgPyBwYXJzZXNTdHIuc3BsaXQoJywnKSA6IFtdOwogICAgICAgIGxldCBwbGF5X2hlYWRlcnMgPSB7fTsKICAgICAgICBpZiAodWEpIHBsYXlfaGVhZGVyc1snVXNlci1BZ2VudCddID0gdWE7CiAgICAgICAgaWYgKHJlZmVyZXIpIHBsYXlfaGVhZGVyc1snUmVmZXJlciddID0gcmVmZXJlcjsKICAgICAgICBsZXQgZmluYWxfdXJsID0gJyc7CiAgICAgICAgbGV0IGp4ID0gMDsKICAgICAgICBmb3IgKGNvbnN0IHBhcnNlIG9mIHBhcnNlcykgewogICAgICAgICAgICBpZiAocGFyc2Uuc3RhcnRzV2l0aCgnaHR0cCcpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIGxldCByZXMgPSBhd2FpdCBfZmV0Y2gocGFyc2UgKyByYXdfdXJsLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KTsKICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoYXdhaXQgcmVzLnRleHQoKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGpzb24udXJsICYmIGpzb24udXJsLnN0YXJ0c1dpdGgoJ2h0dHAnKSkgewogICAgICAgICAgICAgICAgICAgICAgICBmaW5hbF91cmwgPSBqc29uLnVybDsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge30KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFmaW5hbF91cmwgJiYgcmF3X3VybC5zdGFydHNXaXRoKCdodHRwJykpIHsKICAgICAgICAgICAgZmluYWxfdXJsID0gcmF3X3VybDsKICAgICAgICAgICAgaWYgKC8oPzp3d3dcLmlxaXlpfHZcLnFxfHZcLnlvdWt1fHd3d1wubWd0dnx3d3dcLmJpbGliaWxpKVwuY29tLy50ZXN0KHJhd191cmwpKSB7CiAgICAgICAgICAgICAgICBqeCA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcGFyc2U6IGp4LAogICAgICAgICAgICB1cmw6IGZpbmFsX3VybCwKICAgICAgICAgICAgaGVhZGVyOiBwbGF5X2hlYWRlcnMKICAgICAgICB9OwogICAgfQp9Ow== \ No newline at end of file diff --git "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" index 7a5a2929..bcb373ef 100644 --- "a/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" +++ "b/spider/js/\347\225\252\350\214\204\345\260\217\350\257\264[\344\271\246].js" @@ -6,6 +6,7 @@ title: '番茄小说[书]', author: '道长', '类型': '小说', + logo: 'https://www.18zf.net/d/file/p/2023/1107/3ty5orktxrc.jpg', lang: 'ds' }) */ diff --git "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" index d55334d0..9411cfbc 100644 --- "a/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" +++ "b/spider/js/\347\225\252\350\214\204\347\225\205\345\220\254[\345\220\254].js" @@ -5,9 +5,10 @@ quickSearch: 0, title: '番茄畅听', author: 'EylinSir', + logo: 'https://www.18zf.net/d/file/p/2023/1107/3ty5orktxrc.jpg', '类型': '听书', lang: 'ds' }) */ -dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflkKzkuaYnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfnlarojITnlYXlkKwnLAogICAgaG9zdDogJ2h0dHBzOi8vcWtmcWFwaS52djl2LmNuJywKICAgIHVybDogJy9hcGkvZGlzY292ZXI/dGFiPeWQrOS5piZ0eXBlPWZ5Y2xhc3MmZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9e3twYWdlfX0nLAogICAgc2VhcmNoVXJsOiAnL2FwaS9zZWFyY2g/a2V5PSoqJnRhYl90eXBlPTImb2Zmc2V0PSgoZnlwYWdlLTEpKjEwKScsCiAgICBkZXRhaWxVcmw6ICcvYXBpL2RldGFpbD9ib29rX2lkPWZ5aWQnLAogICAgaGVhZGVyczogeydVc2VyLUFnZW50JzogJ1VDX1VBJ30sCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDAsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgZG91YmxlOiB0cnVlLAogICAgcGxheV9wYXJzZTogdHJ1ZSwKICAgIGxpbWl0OiAxMiwKICAgIGNsYXNzX25hbWU6ICfnsr7lk4HlsI/or7Qm55u45aOw6K+E5LmmJuS4lueVjOWOhuWPsiblkI3okZfop6Por7sm5a2m5Lmg5oiQ6ZW/JuaIj+absuiJuuacrybnlJ/mtLvnmb7np5Em5a625bqt5pWZ6IKyJuS6uuaWh+enkeWtpiblhbbku5YnLAogICAgY2xhc3NfdXJsOiAnODk5JjQ0NSYxMiYxMzImNDQ5JjExMyY5NjAmNDUwJjQ0NyYzOScsCiAgICBmaWx0ZXI6IHsKICAgICAgICAiODk5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6Ijg5OSJ9LHsibiI6IumDveW4giIsInYiOiIxIn0seyJuIjoi56m/6LaKIiwidiI6IjM3In0seyJuIjoi546w5Luj6KiA5oOFIiwidiI6IjMifSx7Im4iOiLlj6Tku6PoqIDmg4UiLCJ2IjoiNSJ9LHsibiI6IuaAu+ijgSIsInYiOiIyOSJ9LHsibiI6IueOhOW5uyIsInYiOiI3In0seyJuIjoi6YeN55SfIiwidiI6IjM2In0seyJuIjoi5oKs55aRIiwidiI6IjEwIn0seyJuIjoi54G15byCIiwidiI6IjEwMCJ9LHsibiI6Iuezu+e7nyIsInYiOiIxOSJ9LHsibiI6IuenjeeUsCIsInYiOiIyMyJ9LHsibiI6IueUnOWuoCIsInYiOiI5NiJ9LHsibiI6IuWuoOWmuyIsInYiOiIzMCJ9LHsibiI6IumDveW4gueUn+a0uyIsInYiOiIyIn0seyJuIjoi6LWY5am/IiwidiI6IjI1In0seyJuIjoi5YWI5ama5ZCO54ixIiwidiI6IjI2NSJ9LHsibiI6IuWuq+aWl+WuheaWlyIsInYiOiIyNDYifSx7Im4iOiLpg73luILml6XluLgiLCJ2IjoiMjYxIn0seyJuIjoi5oiY56We6LWY5am/IiwidiI6IjI3In0seyJuIjoi56We5Yy7IiwidiI6IjI2In0seyJuIjoi5b2x6KeG5bCP6K+0IiwidiI6IjQ1In0seyJuIjoi5Zu95YaF5b2x6KeGIiwidiI6Ijk5MSJ9LHsibiI6IuWbveWkluW9seinhiIsInYiOiI5OTIifSx7Im4iOiLnsr7lk4HlsI/or7QiLCJ2IjoiOTcwIn0seyJuIjoi5oKs55aR5o6o55CGIiwidiI6IjE2NSJ9LHsibiI6IuenkeW5u+Wwj+ivtCIsInYiOiIxNjYifSx7Im4iOiLmrabkvqDlsI/or7QiLCJ2IjoiOTkzIn0seyJuIjoi546E5bm75bCP6K+0IiwidiI6Ijk3MSJ9LHsibiI6IueOsOWunuWwj+ivtCIsInYiOiI0MDAifSx7Im4iOiLmg4XmhJ/lsI/or7QiLCJ2IjoiOTcyIn0seyJuIjoi5Lyg57uf546E5bm7IiwidiI6IjI1OCJ9LHsibiI6IueOi+WmgyIsInYiOiI4NSJ9LHsibiI6IuWlh+W5u+S7meS+oCIsInYiOiIyNTkifSx7Im4iOiLokIzlrp0iLCJ2IjoiMjgifSx7Im4iOiLpg73luILohJHmtJ4iLCJ2IjoiMjYyIn0seyJuIjoi6IGM5Zy6IiwidiI6IjEyNyJ9LHsibiI6IuWroeWlsyIsInYiOiI4OCJ9LHsibiI6IumDveW4guS/ruecnyIsInYiOiIxMjQifSx7Im4iOiLlubvmg7PoqIDmg4UiLCJ2IjoiMzIifSx7Im4iOiLnpZ7osaoiLCJ2IjoiMjAifSx7Im4iOiLnqbrpl7QiLCJ2IjoiNDQifSx7Im4iOiLlhbbku5YiLCJ2IjoiMzEifSx7Im4iOiLnjoTlubvoqIDmg4UiLCJ2IjoiMjQ4In0seyJuIjoi546E5bm76ISR5rSeIiwidiI6IjI1NyJ9LHsibiI6IuWOhuWPsuWPpOS7oyIsInYiOiIyNzMifSx7Im4iOiLnp5HlubvmnKvkuJYiLCJ2IjoiOCJ9LHsibiI6IuW5tOS7oyIsInYiOiI3OSJ9LHsibiI6IuWkqeaJjSIsInYiOiI5MCJ9LHsibiI6IuWls+W8uiIsInYiOiI4NiJ9LHsibiI6IuaOqOeQhiIsInYiOiI2MSJ9LHsibiI6IuiFuem7kSIsInYiOiI5MiJ9LHsibiI6IuivuOWkqeS4h+eVjCIsInYiOiI3MSJ9LHsibiI6IuWMu+acryIsInYiOiIyNDcifSx7Im4iOiLmmJ/pmYUiLCJ2IjoiNzcifSx7Im4iOiLpibTlrp0iLCJ2IjoiMTcifSx7Im4iOiLlm6LlrqAiLCJ2IjoiOTQifSx7Im4iOiLmia7njKrlkIPomY4iLCJ2IjoiOTMifSx7Im4iOiLmrabkvqAiLCJ2IjoiMTYifSx7Im4iOiLnjrDoqIDohJHmtJ4iLCJ2IjoiMjY3In0seyJuIjoi6YO95biC56eN55SwIiwidiI6IjI2MyJ9LHsibiI6IuaXoOaVjCIsInYiOiIzODQifSx7Im4iOiLnm5flopMiLCJ2IjoiODEifSx7Im4iOiLpqaznlLIiLCJ2IjoiMjY2In0seyJuIjoi55qH5ZCOIiwidiI6Ijg0In0seyJuIjoi54m556eN5YW1IiwidiI6IjM3NSJ9LHsibiI6IuWkp+WUkCIsInYiOiI3MyJ9LHsibiI6IuWFrOS4uyIsInYiOiI4MyJ9LHsibiI6IuWoseS5kOWciCIsInYiOiI0MyJ9LHsibiI6IumdkuaiheeruemprCIsInYiOiIzODcifSx7Im4iOiLlj6ToqIDohJHmtJ4iLCJ2IjoiMjUzIn0seyJuIjoi5Y6G5Y+y6ISR5rSeIiwidiI6IjI3MiJ9LHsibiI6Iuacq+S4liIsInYiOiI2OCJ9LHsibiI6IuWJkemBkyIsInYiOiI4MCJ9LHsibiI6IueOsOiogOeUnOWuoCIsInYiOiIzOTUifSx7Im4iOiLmuLjmiI/liqjmvKsiLCJ2IjoiNTcifSx7Im4iOiLmtKrojZIiLCJ2IjoiNjYifSx7Im4iOiLlv6vnqb8iLCJ2IjoiMjQifSx7Im4iOiLmmI7mnJ0iLCJ2IjoiMTI2In0seyJuIjoi5aSW5Y2WIiwidiI6Ijc1In0seyJuIjoi5qCh6IqxIiwidiI6IjM4NSJ9LHsibiI6IuWltueIuCIsInYiOiI0MiJ9LHsibiI6IuagoeWbrSIsInYiOiI0In0seyJuIjoi5LiJ5Zu9IiwidiI6IjY3In0seyJuIjoi55u05pKtIiwidiI6IjY5In0seyJuIjoi56m/5LmmIiwidiI6IjM4MiJ9LHsibiI6Iua1t+WymyIsInYiOiI0MCJ9LHsibiI6Iue+jumjnyIsInYiOiI3OCJ9LHsibiI6IuWPjea0viIsInYiOiIzNjkifSx7Im4iOiLnjrDoqIDlpI3ku4ciLCJ2IjoiMjY4In0seyJuIjoi6KW/5ri46KGN55SfIiwidiI6IjM3MyJ9LHsibiI6IuaxgueUnyIsInYiOiIzNzkifSx7Im4iOiLmsJHlm70iLCJ2IjoiMzkwIn0seyJuIjoi5a625bqtIiwidiI6IjEyNSJ9LHsibiI6IuWtpumcuCIsInYiOiI4MiJ9LHsibiI6Iueah+WPlCIsInYiOiI4NyJ9LHsibiI6IuWuoOeJqSIsInYiOiI3NCJ9LHsibiI6IuaXoENQIiwidiI6IjM5MiJ9LHsibiI6IuWls+aJrueUt+ijhSIsInYiOiIzODgifSx7Im4iOiLnvZHmuLgiLCJ2IjoiMzcyIn0seyJuIjoi55eF5aiHIiwidiI6IjM4MCJ9LHsibiI6IueyvueBtSIsInYiOiI4OSJ9LHsibiI6IuiZkOaWhyIsInYiOiI5NSJ9LHsibiI6IumDveW4gumdkuaYpSIsInYiOiIzOTYifSx7Im4iOiLmuIXnqb8iLCJ2IjoiNzYifV19XSwKICAgICAgICAiNDQ1IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0NSJ9LHsibiI6IumDreW+t+e6siIsInYiOiIxMjgifSx7Im4iOiLnlLDov57lhYMiLCJ2IjoiMjAzIn0seyJuIjoi5YiY5YWw6IqzIiwidiI6IjIwMiJ9LHsibiI6IuWwj+WTgSIsInYiOiIxMTQifSx7Im4iOiLoooHpmJTmiJAiLCJ2IjoiMjA0In0seyJuIjoi5Y2V55Sw6IqzIiwidiI6IjIwMSJ9LHsibiI6IuivhOS5piIsInYiOiIxMTAifSx7Im4iOiLnm7jlo7AiLCJ2IjoiMTExIn1dfV0sCiAgICAgICAgIjEyIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjEyIn0seyJuIjoi6a2P5pmL5Y2X5YyX5pydIiwidiI6IjIwOSJ9LHsibiI6IuenpuaxiSIsInYiOiIyMDgifSx7Im4iOiLkuJbnlYzlj7IiLCJ2IjoiMjE0In0seyJuIjoi5ZSQ5a6LIiwidiI6IjIxMCJ9LHsibiI6IuaYjua4hSIsInYiOiIyMTEifSx7Im4iOiLov5HnjrDku6MiLCJ2IjoiMjEzIn0seyJuIjoi5Lit5Zu95Y+yIiwidiI6IjIxMiJ9LHsibiI6IuaImOS6ieWPsiIsInYiOiIyMDYifSx7Im4iOiLlkI3kurrkvKAiLCJ2IjoiMjA3In0seyJuIjoi5Lit5Zu95Y6G5Y+yIiwidiI6IjQwMiJ9LHsibiI6IuS4lueVjOWOhuWPsiIsInYiOiI0MDMifSx7Im4iOiLljoblj7LlsI/or7QiLCJ2IjoiOTg4In0seyJuIjoi5Y6G5Y+y5paH5YyWIiwidiI6IjI0MSJ9XX1dLAogICAgICAgICIxMzIiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiMTMyIn0seyJuIjoi5oiY5LqJIiwidiI6Ijk3In0seyJuIjoi5Lit5Zu95ZCN6JGXIiwidiI6Ijk4In0seyJuIjoi5aSW5Zu95ZCN6JGXIiwidiI6Ijk5In0seyJuIjoi57uP566h5Yqx5b+XIiwidiI6IjI0MiJ9LHsibiI6IuS6uueJqeS8oOiusCIsInYiOiI0MDkifSx7Im4iOiLnu4/lhbjmloflraYiLCJ2IjoiMjQzIn0seyJuIjoi6Z2S5pil5paH5a2mIiwidiI6IjE2OCJ9LHsibiI6IuaImOS6ieWGm+aXhSIsInYiOiI5NzMifV19XSwKICAgICAgICAiNDQ5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0OSJ9LHsibiI6IuazleW+iyIsInYiOiIxNDIifSx7Im4iOiLlv4PnkIYiLCJ2IjoiMTQ2In0seyJuIjoi5b+D55CG5a2mIiwidiI6IjQwNyJ9LHsibiI6IuWwkeWEv+W/g+eQhiIsInYiOiI5ODYifSx7Im4iOiLlv4PnkIbnlpfmhIgiLCJ2IjoiOTk0In0seyJuIjoi5oqV6LWE55CG6LSiIiwidiI6IjE0MyJ9LHsibiI6IuiBjOS4muiBjOWcuiIsInYiOiIxNDUifSx7Im4iOiLnu4/nrqHllYbkuJoiLCJ2IjoiMjM4In0seyJuIjoi5rKf6YCa6KGo6L6+IiwidiI6IjE0NCJ9LHsibiI6IuWKseW/l+aIkOWKnyIsInYiOiIyMzkifV19XSwKICAgICAgICAiMTEzIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjExMyJ9LHsibiI6IuS6rOWJpyIsInYiOiIxNzEifSx7Im4iOiLotorliaciLCJ2IjoiMTcyIn0seyJuIjoi6buE5qKF5oiPIiwidiI6IjE3MyJ9LHsibiI6IuivhOWJpyIsInYiOiIxNzQifSx7Im4iOiLosavliaciLCJ2IjoiMTc1In0seyJuIjoi5piG5puyIiwidiI6IjE3NiJ9LHsibiI6IuiJuuacryIsInYiOiIxMzQifSx7Im4iOiLoibrmnK/mlofljJYiLCJ2IjoiOTQ1In0seyJuIjoi6Z+z5LmQ6Iie6LmIIiwidiI6Ijk0NiJ9LHsibiI6Iue7mOeUuyIsInYiOiI5NTkifSx7Im4iOiLmkYTlvbEiLCJ2IjoiOTYxIn0seyJuIjoi6Ym06LWP55CG6K66IiwidiI6Ijk2MiJ9XX1dLAogICAgICAgICI5NjAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiOTYwIn0seyJuIjoi576O6aOf54O56aWqIiwidiI6IjI0MCJ9LHsibiI6IuaXhea4uCIsInYiOiIxNTgifSx7Im4iOiLlgaXlurflhbvnlJ8iLCJ2IjoiMTU5In0seyJuIjoi6L+Q5Yqo5YGl6LqrIiwidiI6IjQxNyJ9LHsibiI6IuaXtuWwmue+juWmhiIsInYiOiI0MTgifSx7Im4iOiLnvo7po5/kvJHpl7IiLCJ2IjoiNDE5In0seyJuIjoi5a625bGF5peF5ri4IiwidiI6IjQyMCJ9LHsibiI6IumjjuawtOWNoOWNnCIsInYiOiI0MjEifSx7Im4iOiLnmb7np5HluLjor4YiLCJ2IjoiOTYzIn0seyJuIjoi55Sf5rS75oOF5oSfIiwidiI6Ijk2NCJ9XX1dLAogICAgICAgICI0NTAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiNDUwIn0seyJuIjoi5Lqy5a2QIiwidiI6IjQ0NyJ9LHsibiI6IuWpmuWnuyIsInYiOiIyMzQifSx7Im4iOiLnvo7mlociLCJ2IjoiMjMwIn0seyJuIjoi5aSc6K+dIiwidiI6IjIzMiJ9LHsibiI6IuWls+aApyIsInYiOiIyMzEifSx7Im4iOiLlv4PnkIblgaXlurciLCJ2IjoiMjMzIn0seyJuIjoi5oOF5oSf5pWF5LqLIiwidiI6IjIyOSJ9LHsibiI6IuS6p+WQjuaKpOeQhiIsInYiOiIyMjYifSx7Im4iOiLlhL/nq6Xoi7Hor60iLCJ2IjoiMjIyIn0seyJuIjoi5a2V5pyf5L+d5YGlIiwidiI6IjIyNyJ9LHsibiI6IuS6suWtkOWBpeW6tyIsInYiOiIyMjgifSx7Im4iOiLnp5Hmma4iLCJ2IjoiMjIzIn0seyJuIjoi5Zu95a2m5Y6G5Y+yIiwidiI6IjIyNCJ9LHsibiI6IuiDjuaVmeaXqeaVmSIsInYiOiIyMjUifSx7Im4iOiLlhL/nq6XmloflraYiLCJ2IjoiMjIwIn1dfV0sCiAgICAgICAgIjQ0NyI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuWFqOmDqCIsInYiOiI0NDcifSx7Im4iOiLnp5HlrabmioDmnK8iLCJ2IjoiMTAwMCJ9LHsibiI6IuiHqueEtuenkeWtpiIsInYiOiIxMzYifSx7Im4iOiLkvZvlraYiLCJ2IjoiMTE1In0seyJuIjoi56S+56eRIiwidiI6IjIzNyJ9LHsibiI6IuWbveWtpiIsInYiOiIxMTYifSx7Im4iOiLmlaPmlofmiI/liaciLCJ2IjoiMjM2In0seyJuIjoi5paH5YyWIiwidiI6IjExOCJ9LHsibiI6IuaKgOacryIsInYiOiI5NjkifSx7Im4iOiLnp5HlraYiLCJ2IjoiOTc5In0seyJuIjoi5bel5LiaIiwidiI6Ijk4MCJ9LHsibiI6IuWGnOael+eJp+a4lCIsInYiOiI5ODEifSx7Im4iOiLorqHnrpfmnLoiLCJ2IjoiOTgyIn0seyJuIjoi5bu6562R5Zut5p6XIiwidiI6Ijk4MyJ9XX1dLAogICAgICAgICIzOSI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuS6jOasoeWFgyIsInYiOiIzOSJ9LHsibiI6IuWoseS5kCIsInYiOiIxMjEifSx7Im4iOiLnuqrlvZUiLCJ2IjoiMTMzIn0seyJuIjoi5paw6Ze7IiwidiI6IjQ0NiJ9XX1dCiAgICB9LAoKICAgIOS4gOe6pzogYXN5bmMgZnVuY3Rpb24gKHRpZCwgcGcsIGZpbHRlciwgZXh0ZW5kKSB7CiAgICAgICAgbGV0IHBhZ2UgPSBwZyB8fCAxOwogICAgICAgIGxldCB0eXBlSWQgPSAoZXh0ZW5kICYmIGV4dGVuZC50eXBlKSA/IGV4dGVuZC50eXBlIDogdGlkOwogICAgICAgIGxldCBmaW5hbFVybCA9IGAke3RoaXMuaG9zdH0vYXBpL2Rpc2NvdmVyP3RhYj3lkKzkuaYmdHlwZT0ke3R5cGVJZH0mZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9JHtwYWdlfWA7CiAgICAgICAgbGV0IGpzb24gPSBhd2FpdCByZXF1ZXN0KGZpbmFsVXJsKTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoanNvbik7CiAgICAgICAgbGV0IGJvb2tfbGlzdCA9IGRhdGEuY29kZSA9PT0gMjAwID8gZGF0YS5kYXRhIDogW107CiAgICAgICAgbGV0IGQgPSBbXTsKICAgICAgICBib29rX2xpc3QuZm9yRWFjaCgoaXQpID0+IHsKICAgICAgICAgICAgZC5wdXNoKHsKICAgICAgICAgICAgICAgIHRpdGxlOiBpdC5ib29rX25hbWUgfHwgaXQuQm9va05hbWUsCiAgICAgICAgICAgICAgICB1cmw6IGl0LmJvb2tfaWQgfHwgaXQuQm9va0lkLAogICAgICAgICAgICAgICAgZGVzYzogaXQuYXV0aG9yIHx8IGl0LkF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGl0LmFic3RyYWN0IHx8IGl0LkFic3RyYWN0IHx8IGl0LmJvb2tfYWJzdHJhY3RfdjIsCiAgICAgICAgICAgICAgICBwaWNfdXJsOiBpdC50aHVtYl91cmwgfHwgaXQuVGh1bWJVUkwgfHwgaXQuYXVkaW9fdGh1bWJfdXJpCiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KGQpOwogICAgfSwKCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgZGV0YWlsQXBpID0gYCR7dGhpcy5ob3N0fS9hcGkvZGV0YWlsP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgZGV0YWlsSnNvbiA9IGF3YWl0IHJlcXVlc3QoZGV0YWlsQXBpKTsKICAgICAgICBsZXQgZGV0YWlsRGF0YSA9IEpTT04ucGFyc2UoZGV0YWlsSnNvbik7CiAgICAgICAgbGV0IGRhdGEgPSBkZXRhaWxEYXRhLmRhdGEuZGF0YTsKICAgICAgICBsZXQgY2hhcHRlcnNBcGkgPSBgJHt0aGlzLmhvc3R9L2FwaS9ib29rP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgY2hhcHRlcnNKc29uID0gYXdhaXQgcmVxdWVzdChjaGFwdGVyc0FwaSk7CiAgICAgICAgbGV0IGNoYXB0ZXJzRGF0YSA9IEpTT04ucGFyc2UoY2hhcHRlcnNKc29uKTsKICAgICAgICBsZXQgYm9va0RhdGEgPSBjaGFwdGVyc0RhdGEuZGF0YS5kYXRhOwogICAgICAgIGxldCBsaXN0ID0gYm9va0RhdGEuY2hhcHRlckxpc3RXaXRoVm9sdW1lPy5mbGF0KCkgfHwgYm9va0RhdGEuY2hhcHRlckxpc3QgfHwgW107CiAgICAgICAgbGV0IHVybHMgPSBsaXN0Lm1hcChpdCA9PiBpdC50aXRsZSArICckJyArIGl0Lml0ZW1JZCArICdAJyArIGl0LnRpdGxlKS5qb2luKCcjJyk7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdm9kX2lkOiB0aGlzLm9ySWQsCiAgICAgICAgICAgIHZvZF9uYW1lOiBkYXRhLmJvb2tfbmFtZSwKICAgICAgICAgICAgdHlwZV9uYW1lOiBkYXRhLmNhdGVnb3J5LAogICAgICAgICAgICB2b2RfcGljOiBkYXRhLnRodW1iX3VybCB8fCBkYXRhLmV4cGFuZF90aHVtYl91cmwsCiAgICAgICAgICAgIHZvZF9jb250ZW50OiBkYXRhLmFic3RyYWN0IHx8IGRhdGEuYm9va19hYnN0cmFjdF92MiwKICAgICAgICAgICAgdm9kX3JlbWFya3M6IGRhdGEuc3ViX2luZm8sCiAgICAgICAgICAgIHZvZF9kaXJlY3RvcjogZGF0YS5hdXRob3IsCiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfnlarojITnlYXlkKwnLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHVybHMKICAgICAgICB9OwogICAgfSwKCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IGh0bWwgPSBhd2FpdCByZXF1ZXN0KGlucHV0KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgbGV0IGRhdGEgPSBqc29uLmRhdGEuc2VhcmNoX3RhYnNbNF0uZGF0YTsKICAgICAgICBsZXQgZCA9IFtdOwogICAgICAgIGZvciAobGV0IGl0IG9mIGRhdGEuZmlsdGVyKGkgPT4gaS5ib29rX2RhdGEpKSB7CiAgICAgICAgICAgIGxldCBib29rID0gaXQuYm9va19kYXRhWzBdOwogICAgICAgICAgICBkLnB1c2goewogICAgICAgICAgICAgICAgdGl0bGU6IGJvb2suYm9va19uYW1lLAogICAgICAgICAgICAgICAgdXJsOiBib29rLmJvb2tfaWQsCiAgICAgICAgICAgICAgICBkZXNjOiBib29rLmF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGJvb2suYm9va19hYnN0cmFjdCB8fCBib29rLmFic3RyYWN0LAogICAgICAgICAgICAgICAgcGljX3VybDogYm9vay50aHVtYl91cmwKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXRSZXN1bHQoZCk7CiAgICB9LAoKICAgIGxhenk6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IHBhcnRzID0gaW5wdXQuc3BsaXQoJ0AnKTsKICAgICAgICBsZXQgaXRlbUlkID0gcGFydHNbMF07CiAgICAgICAgbGV0IHRvbmVJZCA9ICcxJzsKICAgICAgICBsZXQgY29udGVudF91cmwgPSBgJHt0aGlzLmhvc3R9L2FwaS9jb250ZW50P2l0ZW1faWQ9JHtpdGVtSWR9JnRhYj3lkKzkuaYmdG9uZV9pZD0ke3RvbmVJZH1gOwogICAgICAgIGxldCBqc29uU3RyID0gYXdhaXQgcmVxdWVzdChjb250ZW50X3VybCk7CiAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGpzb25TdHIpOwogICAgICAgIHJldHVybiB7cGFyc2U6IDAsIHVybDogZGF0YS5kYXRhLmNvbnRlbnR9OwogICAgfQp9Ow== \ No newline at end of file +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflkKzkuaYnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfnlarojITnlYXlkKwnLAogICAgaG9zdDogJ2h0dHBzOi8vcWtmcWFwaS52djl2LmNuJywKICAgIHVybDogJy9hcGkvZGlzY292ZXI/dGFiPeWQrOS5piZ0eXBlPWZ5Y2xhc3MmZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9e3twYWdlfX0nLAogICAgc2VhcmNoVXJsOiAnL2FwaS9zZWFyY2g/a2V5PSoqJnRhYl90eXBlPTImb2Zmc2V0PSgoZnlwYWdlLTEpKjEwKScsCiAgICBkZXRhaWxVcmw6ICcvYXBpL2RldGFpbD9ib29rX2lkPWZ5aWQnLAogICAgaGVhZGVyczogeydVc2VyLUFnZW50JzogJ1VDX1VBJ30sCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDAsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgZG91YmxlOiB0cnVlLAogICAgcGxheV9wYXJzZTogdHJ1ZSwKICAgIGxpbWl0OiAxMiwKICAgIGNsYXNzX25hbWU6ICfnsr7lk4HlsI/or7Qm55u45aOw6K+E5LmmJuS4lueVjOWOhuWPsiblkI3okZfop6Por7sm5a2m5Lmg5oiQ6ZW/JuaIj+absuiJuuacrybnlJ/mtLvnmb7np5Em5a625bqt5pWZ6IKyJuS6uuaWh+enkeWtpiblhbbku5YnLAogICAgY2xhc3NfdXJsOiAnODk5JjQ0NSYxMiYxMzImNDQ5JjExMyY5NjAmNDUwJjQ0NyYzOScsCiAgICBmaWx0ZXI6IHsKICAgICAgICAiODk5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6Ijg5OSJ9LHsibiI6IumDveW4giIsInYiOiIxIn0seyJuIjoi56m/6LaKIiwidiI6IjM3In0seyJuIjoi546w5Luj6KiA5oOFIiwidiI6IjMifSx7Im4iOiLlj6Tku6PoqIDmg4UiLCJ2IjoiNSJ9LHsibiI6IuaAu+ijgSIsInYiOiIyOSJ9LHsibiI6IueOhOW5uyIsInYiOiI3In0seyJuIjoi6YeN55SfIiwidiI6IjM2In0seyJuIjoi5oKs55aRIiwidiI6IjEwIn0seyJuIjoi54G15byCIiwidiI6IjEwMCJ9LHsibiI6Iuezu+e7nyIsInYiOiIxOSJ9LHsibiI6IuenjeeUsCIsInYiOiIyMyJ9LHsibiI6IueUnOWuoCIsInYiOiI5NiJ9LHsibiI6IuWuoOWmuyIsInYiOiIzMCJ9LHsibiI6IumDveW4gueUn+a0uyIsInYiOiIyIn0seyJuIjoi6LWY5am/IiwidiI6IjI1In0seyJuIjoi5YWI5ama5ZCO54ixIiwidiI6IjI2NSJ9LHsibiI6IuWuq+aWl+WuheaWlyIsInYiOiIyNDYifSx7Im4iOiLpg73luILml6XluLgiLCJ2IjoiMjYxIn0seyJuIjoi5oiY56We6LWY5am/IiwidiI6IjI3In0seyJuIjoi56We5Yy7IiwidiI6IjI2In0seyJuIjoi5b2x6KeG5bCP6K+0IiwidiI6IjQ1In0seyJuIjoi5Zu95YaF5b2x6KeGIiwidiI6Ijk5MSJ9LHsibiI6IuWbveWkluW9seinhiIsInYiOiI5OTIifSx7Im4iOiLnsr7lk4HlsI/or7QiLCJ2IjoiOTcwIn0seyJuIjoi5oKs55aR5o6o55CGIiwidiI6IjE2NSJ9LHsibiI6IuenkeW5u+Wwj+ivtCIsInYiOiIxNjYifSx7Im4iOiLmrabkvqDlsI/or7QiLCJ2IjoiOTkzIn0seyJuIjoi546E5bm75bCP6K+0IiwidiI6Ijk3MSJ9LHsibiI6IueOsOWunuWwj+ivtCIsInYiOiI0MDAifSx7Im4iOiLmg4XmhJ/lsI/or7QiLCJ2IjoiOTcyIn0seyJuIjoi5Lyg57uf546E5bm7IiwidiI6IjI1OCJ9LHsibiI6IueOi+WmgyIsInYiOiI4NSJ9LHsibiI6IuWlh+W5u+S7meS+oCIsInYiOiIyNTkifSx7Im4iOiLokIzlrp0iLCJ2IjoiMjgifSx7Im4iOiLpg73luILohJHmtJ4iLCJ2IjoiMjYyIn0seyJuIjoi6IGM5Zy6IiwidiI6IjEyNyJ9LHsibiI6IuWroeWlsyIsInYiOiI4OCJ9LHsibiI6IumDveW4guS/ruecnyIsInYiOiIxMjQifSx7Im4iOiLlubvmg7PoqIDmg4UiLCJ2IjoiMzIifSx7Im4iOiLnpZ7osaoiLCJ2IjoiMjAifSx7Im4iOiLnqbrpl7QiLCJ2IjoiNDQifSx7Im4iOiLlhbbku5YiLCJ2IjoiMzEifSx7Im4iOiLnjoTlubvoqIDmg4UiLCJ2IjoiMjQ4In0seyJuIjoi546E5bm76ISR5rSeIiwidiI6IjI1NyJ9LHsibiI6IuWOhuWPsuWPpOS7oyIsInYiOiIyNzMifSx7Im4iOiLnp5HlubvmnKvkuJYiLCJ2IjoiOCJ9LHsibiI6IuW5tOS7oyIsInYiOiI3OSJ9LHsibiI6IuWkqeaJjSIsInYiOiI5MCJ9LHsibiI6IuWls+W8uiIsInYiOiI4NiJ9LHsibiI6IuaOqOeQhiIsInYiOiI2MSJ9LHsibiI6IuiFuem7kSIsInYiOiI5MiJ9LHsibiI6IuivuOWkqeS4h+eVjCIsInYiOiI3MSJ9LHsibiI6IuWMu+acryIsInYiOiIyNDcifSx7Im4iOiLmmJ/pmYUiLCJ2IjoiNzcifSx7Im4iOiLpibTlrp0iLCJ2IjoiMTcifSx7Im4iOiLlm6LlrqAiLCJ2IjoiOTQifSx7Im4iOiLmia7njKrlkIPomY4iLCJ2IjoiOTMifSx7Im4iOiLmrabkvqAiLCJ2IjoiMTYifSx7Im4iOiLnjrDoqIDohJHmtJ4iLCJ2IjoiMjY3In0seyJuIjoi6YO95biC56eN55SwIiwidiI6IjI2MyJ9LHsibiI6IuaXoOaVjCIsInYiOiIzODQifSx7Im4iOiLnm5flopMiLCJ2IjoiODEifSx7Im4iOiLpqaznlLIiLCJ2IjoiMjY2In0seyJuIjoi55qH5ZCOIiwidiI6Ijg0In0seyJuIjoi54m556eN5YW1IiwidiI6IjM3NSJ9LHsibiI6IuWkp+WUkCIsInYiOiI3MyJ9LHsibiI6IuWFrOS4uyIsInYiOiI4MyJ9LHsibiI6IuWoseS5kOWciCIsInYiOiI0MyJ9LHsibiI6IumdkuaiheeruemprCIsInYiOiIzODcifSx7Im4iOiLlj6ToqIDohJHmtJ4iLCJ2IjoiMjUzIn0seyJuIjoi5Y6G5Y+y6ISR5rSeIiwidiI6IjI3MiJ9LHsibiI6Iuacq+S4liIsInYiOiI2OCJ9LHsibiI6IuWJkemBkyIsInYiOiI4MCJ9LHsibiI6IueOsOiogOeUnOWuoCIsInYiOiIzOTUifSx7Im4iOiLmuLjmiI/liqjmvKsiLCJ2IjoiNTcifSx7Im4iOiLmtKrojZIiLCJ2IjoiNjYifSx7Im4iOiLlv6vnqb8iLCJ2IjoiMjQifSx7Im4iOiLmmI7mnJ0iLCJ2IjoiMTI2In0seyJuIjoi5aSW5Y2WIiwidiI6Ijc1In0seyJuIjoi5qCh6IqxIiwidiI6IjM4NSJ9LHsibiI6IuWltueIuCIsInYiOiI0MiJ9LHsibiI6IuagoeWbrSIsInYiOiI0In0seyJuIjoi5LiJ5Zu9IiwidiI6IjY3In0seyJuIjoi55u05pKtIiwidiI6IjY5In0seyJuIjoi56m/5LmmIiwidiI6IjM4MiJ9LHsibiI6Iua1t+WymyIsInYiOiI0MCJ9LHsibiI6Iue+jumjnyIsInYiOiI3OCJ9LHsibiI6IuWPjea0viIsInYiOiIzNjkifSx7Im4iOiLnjrDoqIDlpI3ku4ciLCJ2IjoiMjY4In0seyJuIjoi6KW/5ri46KGN55SfIiwidiI6IjM3MyJ9LHsibiI6IuaxgueUnyIsInYiOiIzNzkifSx7Im4iOiLmsJHlm70iLCJ2IjoiMzkwIn0seyJuIjoi5a625bqtIiwidiI6IjEyNSJ9LHsibiI6IuWtpumcuCIsInYiOiI4MiJ9LHsibiI6Iueah+WPlCIsInYiOiI4NyJ9LHsibiI6IuWuoOeJqSIsInYiOiI3NCJ9LHsibiI6IuaXoENQIiwidiI6IjM5MiJ9LHsibiI6IuWls+aJrueUt+ijhSIsInYiOiIzODgifSx7Im4iOiLnvZHmuLgiLCJ2IjoiMzcyIn0seyJuIjoi55eF5aiHIiwidiI6IjM4MCJ9LHsibiI6IueyvueBtSIsInYiOiI4OSJ9LHsibiI6IuiZkOaWhyIsInYiOiI5NSJ9LHsibiI6IumDveW4gumdkuaYpSIsInYiOiIzOTYifSx7Im4iOiLmuIXnqb8iLCJ2IjoiNzYifV19XSwKICAgICAgICAiNDQ1IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0NSJ9LHsibiI6IumDreW+t+e6siIsInYiOiIxMjgifSx7Im4iOiLnlLDov57lhYMiLCJ2IjoiMjAzIn0seyJuIjoi5YiY5YWw6IqzIiwidiI6IjIwMiJ9LHsibiI6IuWwj+WTgSIsInYiOiIxMTQifSx7Im4iOiLoooHpmJTmiJAiLCJ2IjoiMjA0In0seyJuIjoi5Y2V55Sw6IqzIiwidiI6IjIwMSJ9LHsibiI6IuivhOS5piIsInYiOiIxMTAifSx7Im4iOiLnm7jlo7AiLCJ2IjoiMTExIn1dfV0sCiAgICAgICAgIjEyIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjEyIn0seyJuIjoi6a2P5pmL5Y2X5YyX5pydIiwidiI6IjIwOSJ9LHsibiI6IuenpuaxiSIsInYiOiIyMDgifSx7Im4iOiLkuJbnlYzlj7IiLCJ2IjoiMjE0In0seyJuIjoi5ZSQ5a6LIiwidiI6IjIxMCJ9LHsibiI6IuaYjua4hSIsInYiOiIyMTEifSx7Im4iOiLov5HnjrDku6MiLCJ2IjoiMjEzIn0seyJuIjoi5Lit5Zu95Y+yIiwidiI6IjIxMiJ9LHsibiI6IuaImOS6ieWPsiIsInYiOiIyMDYifSx7Im4iOiLlkI3kurrkvKAiLCJ2IjoiMjA3In0seyJuIjoi5Lit5Zu95Y6G5Y+yIiwidiI6IjQwMiJ9LHsibiI6IuS4lueVjOWOhuWPsiIsInYiOiI0MDMifSx7Im4iOiLljoblj7LlsI/or7QiLCJ2IjoiOTg4In0seyJuIjoi5Y6G5Y+y5paH5YyWIiwidiI6IjI0MSJ9XX1dLAogICAgICAgICIxMzIiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiMTMyIn0seyJuIjoi5oiY5LqJIiwidiI6Ijk3In0seyJuIjoi5Lit5Zu95ZCN6JGXIiwidiI6Ijk4In0seyJuIjoi5aSW5Zu95ZCN6JGXIiwidiI6Ijk5In0seyJuIjoi57uP566h5Yqx5b+XIiwidiI6IjI0MiJ9LHsibiI6IuS6uueJqeS8oOiusCIsInYiOiI0MDkifSx7Im4iOiLnu4/lhbjmloflraYiLCJ2IjoiMjQzIn0seyJuIjoi6Z2S5pil5paH5a2mIiwidiI6IjE2OCJ9LHsibiI6IuaImOS6ieWGm+aXhSIsInYiOiI5NzMifV19XSwKICAgICAgICAiNDQ5IjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjQ0OSJ9LHsibiI6IuazleW+iyIsInYiOiIxNDIifSx7Im4iOiLlv4PnkIYiLCJ2IjoiMTQ2In0seyJuIjoi5b+D55CG5a2mIiwidiI6IjQwNyJ9LHsibiI6IuWwkeWEv+W/g+eQhiIsInYiOiI5ODYifSx7Im4iOiLlv4PnkIbnlpfmhIgiLCJ2IjoiOTk0In0seyJuIjoi5oqV6LWE55CG6LSiIiwidiI6IjE0MyJ9LHsibiI6IuiBjOS4muiBjOWcuiIsInYiOiIxNDUifSx7Im4iOiLnu4/nrqHllYbkuJoiLCJ2IjoiMjM4In0seyJuIjoi5rKf6YCa6KGo6L6+IiwidiI6IjE0NCJ9LHsibiI6IuWKseW/l+aIkOWKnyIsInYiOiIyMzkifV19XSwKICAgICAgICAiMTEzIjogW3trZXk6ICJ0eXBlIiwgbmFtZTogIuexu+WeiyIsIHZhbHVlOiBbeyJuIjoi5YWo6YOoIiwidiI6IjExMyJ9LHsibiI6IuS6rOWJpyIsInYiOiIxNzEifSx7Im4iOiLotorliaciLCJ2IjoiMTcyIn0seyJuIjoi6buE5qKF5oiPIiwidiI6IjE3MyJ9LHsibiI6IuivhOWJpyIsInYiOiIxNzQifSx7Im4iOiLosavliaciLCJ2IjoiMTc1In0seyJuIjoi5piG5puyIiwidiI6IjE3NiJ9LHsibiI6IuiJuuacryIsInYiOiIxMzQifSx7Im4iOiLoibrmnK/mlofljJYiLCJ2IjoiOTQ1In0seyJuIjoi6Z+z5LmQ6Iie6LmIIiwidiI6Ijk0NiJ9LHsibiI6Iue7mOeUuyIsInYiOiI5NTkifSx7Im4iOiLmkYTlvbEiLCJ2IjoiOTYxIn0seyJuIjoi6Ym06LWP55CG6K66IiwidiI6Ijk2MiJ9XX1dLAogICAgICAgICI5NjAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiOTYwIn0seyJuIjoi576O6aOf54O56aWqIiwidiI6IjI0MCJ9LHsibiI6IuaXhea4uCIsInYiOiIxNTgifSx7Im4iOiLlgaXlurflhbvnlJ8iLCJ2IjoiMTU5In0seyJuIjoi6L+Q5Yqo5YGl6LqrIiwidiI6IjQxNyJ9LHsibiI6IuaXtuWwmue+juWmhiIsInYiOiI0MTgifSx7Im4iOiLnvo7po5/kvJHpl7IiLCJ2IjoiNDE5In0seyJuIjoi5a625bGF5peF5ri4IiwidiI6IjQyMCJ9LHsibiI6IumjjuawtOWNoOWNnCIsInYiOiI0MjEifSx7Im4iOiLnmb7np5HluLjor4YiLCJ2IjoiOTYzIn0seyJuIjoi55Sf5rS75oOF5oSfIiwidiI6Ijk2NCJ9XX1dLAogICAgICAgICI0NTAiOiBbe2tleTogInR5cGUiLCBuYW1lOiAi57G75Z6LIiwgdmFsdWU6IFt7Im4iOiLlhajpg6giLCJ2IjoiNDUwIn0seyJuIjoi5Lqy5a2QIiwidiI6IjQ0NyJ9LHsibiI6IuWpmuWnuyIsInYiOiIyMzQifSx7Im4iOiLnvo7mlociLCJ2IjoiMjMwIn0seyJuIjoi5aSc6K+dIiwidiI6IjIzMiJ9LHsibiI6IuWls+aApyIsInYiOiIyMzEifSx7Im4iOiLlv4PnkIblgaXlurciLCJ2IjoiMjMzIn0seyJuIjoi5oOF5oSf5pWF5LqLIiwidiI6IjIyOSJ9LHsibiI6IuS6p+WQjuaKpOeQhiIsInYiOiIyMjYifSx7Im4iOiLlhL/nq6Xoi7Hor60iLCJ2IjoiMjIyIn0seyJuIjoi5a2V5pyf5L+d5YGlIiwidiI6IjIyNyJ9LHsibiI6IuS6suWtkOWBpeW6tyIsInYiOiIyMjgifSx7Im4iOiLnp5Hmma4iLCJ2IjoiMjIzIn0seyJuIjoi5Zu95a2m5Y6G5Y+yIiwidiI6IjIyNCJ9LHsibiI6IuiDjuaVmeaXqeaVmSIsInYiOiIyMjUifSx7Im4iOiLlhL/nq6XmloflraYiLCJ2IjoiMjIwIn1dfV0sCiAgICAgICAgIjQ0NyI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuWFqOmDqCIsInYiOiI0NDcifSx7Im4iOiLnp5HlrabmioDmnK8iLCJ2IjoiMTAwMCJ9LHsibiI6IuiHqueEtuenkeWtpiIsInYiOiIxMzYifSx7Im4iOiLkvZvlraYiLCJ2IjoiMTE1In0seyJuIjoi56S+56eRIiwidiI6IjIzNyJ9LHsibiI6IuWbveWtpiIsInYiOiIxMTYifSx7Im4iOiLmlaPmlofmiI/liaciLCJ2IjoiMjM2In0seyJuIjoi5paH5YyWIiwidiI6IjExOCJ9LHsibiI6IuaKgOacryIsInYiOiI5NjkifSx7Im4iOiLnp5HlraYiLCJ2IjoiOTc5In0seyJuIjoi5bel5LiaIiwidiI6Ijk4MCJ9LHsibiI6IuWGnOael+eJp+a4lCIsInYiOiI5ODEifSx7Im4iOiLorqHnrpfmnLoiLCJ2IjoiOTgyIn0seyJuIjoi5bu6562R5Zut5p6XIiwidiI6Ijk4MyJ9XX1dLAogICAgICAgICIzOSI6IFt7a2V5OiAidHlwZSIsIG5hbWU6ICLnsbvlnosiLCB2YWx1ZTogW3sibiI6IuS6jOasoeWFgyIsInYiOiIzOSJ9LHsibiI6IuWoseS5kCIsInYiOiIxMjEifSx7Im4iOiLnuqrlvZUiLCJ2IjoiMTMzIn0seyJuIjoi5paw6Ze7IiwidiI6IjQ0NiJ9XX1dCiAgICB9LAoKICAgIOS4gOe6pzogYXN5bmMgZnVuY3Rpb24gKHRpZCwgcGcsIGZpbHRlciwgZXh0ZW5kKSB7CiAgICAgICAgbGV0IHBhZ2UgPSBwZyB8fCAxOwogICAgICAgIGxldCB0eXBlSWQgPSAoZXh0ZW5kICYmIGV4dGVuZC50eXBlKSA/IGV4dGVuZC50eXBlIDogdGlkOwogICAgICAgIGxldCBmaW5hbFVybCA9IGAke3RoaXMuaG9zdH0vYXBpL2Rpc2NvdmVyP3RhYj3lkKzkuaYmdHlwZT0ke3R5cGVJZH0mZ2VuZGVyPTImZ2VucmVfdHlwZT0xJnBhZ2U9JHtwYWdlfWA7CiAgICAgICAgbGV0IGpzb24gPSBhd2FpdCByZXF1ZXN0KGZpbmFsVXJsKTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoanNvbik7CiAgICAgICAgbGV0IGJvb2tfbGlzdCA9IGRhdGEuY29kZSA9PT0gMjAwID8gZGF0YS5kYXRhIDogW107CiAgICAgICAgbGV0IGQgPSBbXTsKICAgICAgICBib29rX2xpc3QuZm9yRWFjaCgoaXQpID0+IHsKICAgICAgICAgICAgZC5wdXNoKHsKICAgICAgICAgICAgICAgIHRpdGxlOiBpdC5ib29rX25hbWUgfHwgaXQuQm9va05hbWUsCiAgICAgICAgICAgICAgICB1cmw6IGl0LmJvb2tfaWQgfHwgaXQuQm9va0lkLAogICAgICAgICAgICAgICAgZGVzYzogaXQuYXV0aG9yIHx8IGl0LkF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGl0LmFic3RyYWN0IHx8IGl0LkFic3RyYWN0IHx8IGl0LmJvb2tfYWJzdHJhY3RfdjIsCiAgICAgICAgICAgICAgICBwaWNfdXJsOiBpdC50aHVtYl91cmwgfHwgaXQuVGh1bWJVUkwgfHwgaXQuYXVkaW9fdGh1bWJfdXJpCiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KGQpOwogICAgfSwKCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgZGV0YWlsQXBpID0gYCR7dGhpcy5ob3N0fS9hcGkvZGV0YWlsP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgZGV0YWlsSnNvbiA9IGF3YWl0IHJlcXVlc3QoZGV0YWlsQXBpKTsKICAgICAgICBsZXQgZGV0YWlsRGF0YSA9IEpTT04ucGFyc2UoZGV0YWlsSnNvbik7CiAgICAgICAgbGV0IGRhdGEgPSBkZXRhaWxEYXRhLmRhdGEuZGF0YTsKICAgICAgICBsZXQgY2hhcHRlcnNBcGkgPSBgJHt0aGlzLmhvc3R9L2FwaS9ib29rP2Jvb2tfaWQ9JHt0aGlzLm9ySWR9YDsKICAgICAgICBsZXQgY2hhcHRlcnNKc29uID0gYXdhaXQgcmVxdWVzdChjaGFwdGVyc0FwaSk7CiAgICAgICAgbGV0IGNoYXB0ZXJzRGF0YSA9IEpTT04ucGFyc2UoY2hhcHRlcnNKc29uKTsKICAgICAgICBsZXQgYm9va0RhdGEgPSBjaGFwdGVyc0RhdGEuZGF0YS5kYXRhOwogICAgICAgIGxldCBsaXN0ID0gYm9va0RhdGEuY2hhcHRlckxpc3RXaXRoVm9sdW1lPy5mbGF0KCkgfHwgYm9va0RhdGEuY2hhcHRlckxpc3QgfHwgW107CiAgICAgICAgbGV0IHVybHMgPSBsaXN0Lm1hcChpdCA9PiBpdC50aXRsZSArICckJyArIGl0Lml0ZW1JZCArICdAJyArIGl0LnRpdGxlKS5qb2luKCcjJyk7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdm9kX2lkOiB0aGlzLm9ySWQsCiAgICAgICAgICAgIHZvZF9uYW1lOiBkYXRhLmJvb2tfbmFtZSwKICAgICAgICAgICAgdHlwZV9uYW1lOiBkYXRhLmNhdGVnb3J5LAogICAgICAgICAgICB2b2RfcGljOiBkYXRhLnRodW1iX3VybCB8fCBkYXRhLmV4cGFuZF90aHVtYl91cmwsCiAgICAgICAgICAgIHZvZF9jb250ZW50OiBkYXRhLmFic3RyYWN0IHx8IGRhdGEuYm9va19hYnN0cmFjdF92MiwKICAgICAgICAgICAgdm9kX3JlbWFya3M6IGRhdGEuc3ViX2luZm8sCiAgICAgICAgICAgIHZvZF9kaXJlY3RvcjogZGF0YS5hdXRob3IsCiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfnlarojITnlYXlkKwnLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHVybHMKICAgICAgICB9OwogICAgfSwKCiAgICDmkJzntKI6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IGh0bWwgPSBhd2FpdCByZXF1ZXN0KGlucHV0KTsKICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgbGV0IGRhdGEgPSBqc29uLmRhdGEuc2VhcmNoX3RhYnNbNF0uZGF0YTsKICAgICAgICBsZXQgZCA9IFtdOwogICAgICAgIGZvciAobGV0IGl0IG9mIGRhdGEuZmlsdGVyKGkgPT4gaS5ib29rX2RhdGEpKSB7CiAgICAgICAgICAgIGxldCBib29rID0gaXQuYm9va19kYXRhWzBdOwogICAgICAgICAgICBkLnB1c2goewogICAgICAgICAgICAgICAgdGl0bGU6IGJvb2suYm9va19uYW1lLAogICAgICAgICAgICAgICAgdXJsOiBib29rLmJvb2tfaWQsCiAgICAgICAgICAgICAgICBkZXNjOiBib29rLmF1dGhvciwKICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGJvb2suYm9va19hYnN0cmFjdCB8fCBib29rLmFic3RyYWN0LAogICAgICAgICAgICAgICAgcGljX3VybDogYm9vay50aHVtYl91cmwKICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZXRSZXN1bHQoZCk7CiAgICB9LAoKICAgIGxhenk6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQge2lucHV0fSA9IHRoaXM7CiAgICAgICAgbGV0IHBhcnRzID0gaW5wdXQuc3BsaXQoJ0AnKTsKICAgICAgICBsZXQgaXRlbUlkID0gcGFydHNbMF07CiAgICAgICAgbGV0IHRvbmVJZCA9ICcxJzsKICAgICAgICBsZXQgY29udGVudF91cmwgPSBgJHt0aGlzLmhvc3R9L2FwaS9jb250ZW50P2l0ZW1faWQ9JHtpdGVtSWR9JnRhYj3lkKzkuaYmdG9uZV9pZD0ke3RvbmVJZH1gOwogICAgICAgIGxldCBqc29uU3RyID0gYXdhaXQgcmVxdWVzdChjb250ZW50X3VybCk7CiAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGpzb25TdHIpOwogICAgICAgIHJldHVybiB7cGFyc2U6IDAsIHVybDogZGF0YS5kYXRhLmNvbnRlbnR9OwogICAgfQp9Ow== diff --git "a/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" "b/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" index ac10661c..001dd9a4 100644 --- "a/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" +++ "b/spider/js/\347\225\252\350\214\204\347\237\255\345\211\247[\347\237\255].js" @@ -4,6 +4,7 @@ filterable: 0, quickSearch: 0, title: '番茄短剧', + logo: 'https://www.18zf.net/d/file/p/2023/1107/3ty5orktxrc.jpg', '类型': '影视', lang: 'ds' }) @@ -177,4 +178,4 @@ var rule = { }); return VODS }, -} \ No newline at end of file +} diff --git "a/spider/js/\350\277\275\346\226\260\345\244\247\345\205\250.js" "b/spider/js/\350\277\275\346\226\260\345\244\247\345\205\250.js" new file mode 100644 index 00000000..e7a48126 --- /dev/null +++ "b/spider/js/\350\277\275\346\226\260\345\244\247\345\205\250.js" @@ -0,0 +1,13 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 0, + title: '追新大全', + author: 'EylinSir', + '类型': '影视', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflvbHop4YnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfov73mlrDlpKflhagnLAogICAgaG9zdDogJ2h0dHA6Ly96eHlzLmdhb3pob3Vrai5jbicsCiAgICBob21lVXJsOiAnaHR0cDovL3p4eXMuZ2FvemhvdWtqLmNuJywKICAgIHVybDogJy9wdWJsaWMvP3NlcnZpY2U9QXBwLk1vdi5HZXRPbmxpbmVMaXN0JnR5cGVfaWQ9ZnljbGFzcyZwYWdlPWZ5cGFnZSZsaW1pdD0xOCcsCiAgICBzZWFyY2hVcmw6ICcvcHVibGljLz9zZXJ2aWNlPUFwcC5Nb3YuU2VhcmNoVm9kJmtleT0qKicsCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDAsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgdGltZW91dDogMTAwMDAsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAga2V5OiAnJywKICAgIGl2OiAnMTIzNDU2Nzg5MDEyMzQ1NicsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgJ1VzZXItQWdlbnQnOiAnb2todHRwLzMuMTIuMCcsCiAgICAgICAgJ0Nvbm5lY3Rpb24nOiAnS2VlcC1BbGl2ZScsCiAgICAgICAgJ0FjY2VwdC1FbmNvZGluZyc6ICdnemlwJwogICAgfSwKICAgIAogICAgY2xhc3NfcGFyc2U6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBpZiAoIXRoaXMuaG9zdCkgcmV0dXJuIHsgY2xhc3M6IFtdLCBmaWx0ZXJzOiB7fSB9OwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGNsYXNzOiBbCiAgICAgICAgICAgICAgICB7ICd0eXBlX2lkJzogJzEnLCAndHlwZV9uYW1lJzogJ+eUteW9sScgfSwKICAgICAgICAgICAgICAgIHsgJ3R5cGVfaWQnOiAnMicsICd0eXBlX25hbWUnOiAn6L+e57ut5YmnJyB9LAogICAgICAgICAgICAgICAgeyAndHlwZV9pZCc6ICczJywgJ3R5cGVfbmFtZSc6ICfnu7zoibonIH0sCiAgICAgICAgICAgICAgICB7ICd0eXBlX2lkJzogJzQnLCAndHlwZV9uYW1lJzogJ+WKqOa8qycgfQogICAgICAgICAgICBdLAogICAgICAgICAgICBmaWx0ZXJzOiB7fQogICAgICAgIH07CiAgICB9LAoKICAgIOmihOWkhOeQhjogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCByZXNwMSA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3B1YmxpYy8/c2VydmljZT1BcHAuTW92LkdldFR5cGVMaXN0YCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgICAgIGxldCB0ZXh0MSA9IGF3YWl0IHJlc3AxLnRleHQoKTsKICAgICAgICAgICAgaWYgKHRleHQxLnN0YXJ0c1dpdGgoJ++7vycpKSB0ZXh0MSA9IHRleHQxLnN1YnN0cmluZygxKTsKICAgICAgICAgICAgbGV0IGRhdGExID0gSlNPTi5wYXJzZSh0ZXh0MSk7CiAgICAgICAgICAgIGxldCBzaWduX3N0YXJ0ID0gKGRhdGExLkRhdGEgfHwgW10pLmZpbmQoaSA9PiBpLnR5cGVfaWQudG9TdHJpbmcoKSA9PT0gJzEnKT8udHlwZV91bmlvbiB8fCAnJzsKICAgICAgICAgICAgbGV0IHJlc3AyID0gYXdhaXQgX2ZldGNoKGAke3RoaXMuaG9zdH0vcHVibGljLz9zZXJ2aWNlPUFwcC5Nb3YuR2V0QWRUeXBlYCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgICAgIGxldCB0ZXh0MiA9IGF3YWl0IHJlc3AyLnRleHQoKTsKICAgICAgICAgICAgaWYgKHRleHQyLnN0YXJ0c1dpdGgoJ++7vycpKSB0ZXh0MiA9IHRleHQyLnN1YnN0cmluZygxKTsKICAgICAgICAgICAgbGV0IGRhdGEyID0gSlNPTi5wYXJzZSh0ZXh0Mik7CiAgICAgICAgICAgIGxldCBzaWduX2VuZCA9IGRhdGEyLkRhdGEudG1wIHx8ICcnOwogICAgICAgICAgICBsZXQgZnVsbEtleSA9IHNpZ25fc3RhcnQgKyBzaWduX2VuZDsKICAgICAgICAgICAgaWYgKGZ1bGxLZXkubGVuZ3RoID49IDE2KSB7CiAgICAgICAgICAgICAgICB0aGlzLmtleSA9IGZ1bGxLZXkuc3Vic3RyaW5nKDAsIDE2KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgY29uc29sZS5lcnJvcign5Yid5aeL5YyWIEtleSDlpLHotKU6JywgZSk7CiAgICAgICAgICAgIHRoaXMuaG9zdCA9ICcnOwogICAgICAgIH0KICAgIH0sCiAgICAKICAgIOaOqOiNkDogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGlmICghdGhpcy5ob3N0KSByZXR1cm4gc2V0UmVzdWx0KFtdKTsKICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3B1YmxpYy8/c2VydmljZT1BcHAuTW92LkdldEhvbWVMZXZlbGAsIHsgaGVhZGVyczogdGhpcy5oZWFkZXJzIH0pOwogICAgICAgIGxldCB0ZXh0ID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgaWYgKHRleHQuc3RhcnRzV2l0aCgn77u/JykpIHRleHQgPSB0ZXh0LnN1YnN0cmluZygxKTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UodGV4dCk7CiAgICAgICAgCiAgICAgICAgbGV0IHZpZGVvcyA9IHR5cGVvZiBkYXRhID09PSAnb2JqZWN0JyAmJiBkYXRhICE9PSBudWxsID8gCiAgICAgICAgICAgIE9iamVjdC52YWx1ZXMoZGF0YSkKICAgICAgICAgICAgICAgIC5maWx0ZXIoaXRlbSA9PiB0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcgJiYgaXRlbSAhPT0gbnVsbCkKICAgICAgICAgICAgICAgIC5mbGF0TWFwKGl0ZW0gPT4gT2JqZWN0LnZhbHVlcyhpdGVtKSkKICAgICAgICAgICAgICAgIC5maWx0ZXIoQXJyYXkuaXNBcnJheSkKICAgICAgICAgICAgICAgIC5mbGF0TWFwKGxpc3QgPT4gbGlzdC5tYXAoayA9PiAoewogICAgICAgICAgICAgICAgICAgIHRpdGxlOiBrLnZvZF9uYW1lLAogICAgICAgICAgICAgICAgICAgIHVybDogYCR7dGhpcy5ob3N0fS9wdWJsaWMvP3NlcnZpY2U9QXBwLk1vdi5HZXRPbmxpbmVNdkJ5SWQmdm9kaWQ9JHtrLnZvZF9pZH1gLAogICAgICAgICAgICAgICAgICAgIGRlc2M6IGsudm9kX3JlbWFya3MsCiAgICAgICAgICAgICAgICAgICAgcGljX3VybDogay52b2RfcGljLAogICAgICAgICAgICAgICAgICAgIHZvZF95ZWFyOiBrLnZvZF95ZWFyLAogICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGsudm9kX2NvbnRlbnQKICAgICAgICAgICAgICAgIH0pKSkKICAgICAgICAgICAgOiBbXTsKICAgICAgICAKICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHZpZGVvcyk7CiAgICB9LAogICAgCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uICh0aWQsIHBnLCBmaWx0ZXIsIGV4dGVuZCkgewogICAgICAgIGlmICghdGhpcy5ob3N0KSByZXR1cm4gc2V0UmVzdWx0KFtdKTsKICAgICAgICBsZXQgdXJsID0gYCR7dGhpcy5ob3N0fS9wdWJsaWMvP3NlcnZpY2U9QXBwLk1vdi5HZXRPbmxpbmVMaXN0JnR5cGVfaWQ9JHt0aWR9JnBhZ2U9JHtwZ30mbGltaXQ9MThgOwogICAgICAgIGxldCByZXNwID0gYXdhaXQgX2ZldGNoKHVybCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgbGV0IHRleHQgPSBhd2FpdCByZXNwLnRleHQoKTsKICAgICAgICBpZiAodGV4dC5zdGFydHNXaXRoKCfvu78nKSkgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDEpOwogICAgICAgIGxldCBkYXRhID0gSlNPTi5wYXJzZSh0ZXh0KTsKICAgICAgICBsZXQgdmlkZW9zID0gKGRhdGEuRGF0YSB8fCBbXSkubWFwKGkgPT4gKHsKICAgICAgICAgICAgdGl0bGU6IGkudm9kX25hbWUsCiAgICAgICAgICAgIHVybDogYCR7dGhpcy5ob3N0fS9wdWJsaWMvP3NlcnZpY2U9QXBwLk1vdi5HZXRPbmxpbmVNdkJ5SWQmdm9kaWQ9JHtpLnZvZF9pZH1gLAogICAgICAgICAgICBkZXNjOiBpLnZvZF9yZW1hcmtzLAogICAgICAgICAgICBwaWNfdXJsOiBpLnZvZF9waWMsCiAgICAgICAgICAgIHZvZF95ZWFyOiBpLnZvZF95ZWFyLAogICAgICAgICAgICBjb250ZW50OiBpLnZvZF9jb250ZW50CiAgICAgICAgfSkpOwogICAgICAgIHJldHVybiBzZXRSZXN1bHQodmlkZW9zKTsKICAgIH0sCiAgICAKICAgIOS6jOe6pzogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCB2b2RJZCA9IHRoaXMuaW5wdXQubWF0Y2goL3ZvZGlkPShcZCspLylbMV07CiAgICAgICAgbGV0IHVybCA9IGAke3RoaXMuaG9zdH0vcHVibGljLz9zZXJ2aWNlPUFwcC5Nb3YuR2V0T25saW5lTXZCeUlkJnZvZGlkPSR7dm9kSWR9YDsKICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaCh1cmwsIHsgaGVhZGVyczogdGhpcy5oZWFkZXJzIH0pOwogICAgICAgIGxldCB0ZXh0ID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgaWYgKHRleHQuc3RhcnRzV2l0aCgn77u/JykpIHRleHQgPSB0ZXh0LnN1YnN0cmluZygxKTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UodGV4dCk7CiAgICAgICAgbGV0IGZpcnN0SXRlbSA9IChkYXRhLkRhdGEgfHwgW10pLmZpbmQoaSA9PiB0eXBlb2YgaSA9PT0gJ29iamVjdCcgJiYgaSAhPT0gbnVsbCk7CiAgICAgICAgCiAgICAgICAgaWYgKGZpcnN0SXRlbSkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgdm9kX2lkOiBmaXJzdEl0ZW0udm9kX2lkLnRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICB2b2RfbmFtZTogZmlyc3RJdGVtLnZvZF9uYW1lLAogICAgICAgICAgICAgICAgdm9kX3BpYzogZmlyc3RJdGVtLnZvZF9waWMsCiAgICAgICAgICAgICAgICB2b2RfcmVtYXJrczogZmlyc3RJdGVtLnZvZF9yZW1hcmtzLAogICAgICAgICAgICAgICAgdm9kX3llYXI6IGZpcnN0SXRlbS52b2RfeWVhciwKICAgICAgICAgICAgICAgIHZvZF9hcmVhOiBmaXJzdEl0ZW0udm9kX2FyZWEsCiAgICAgICAgICAgICAgICB2b2RfYWN0b3I6IGZpcnN0SXRlbS52b2RfYWN0b3IsCiAgICAgICAgICAgICAgICB2b2RfY29udGVudDogZmlyc3RJdGVtLnZvZF9jb250ZW50LAogICAgICAgICAgICAgICAgdm9kX3BsYXlfZnJvbTogZmlyc3RJdGVtLnZvZF9wbGF5X2Zyb20sCiAgICAgICAgICAgICAgICB2b2RfcGxheV91cmw6IGZpcnN0SXRlbS52b2RfcGxheV91cmwsCiAgICAgICAgICAgICAgICB0eXBlX25hbWU6IGZpcnN0SXRlbS52b2RfY2xhc3MKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHt9OwogICAgfSwKICAgIAogICAg5pCc57SiOiBhc3luYyBmdW5jdGlvbiAoKSB7CiAgICAgICAgaWYgKCF0aGlzLmhvc3QpIHJldHVybiBzZXRSZXN1bHQoW10pOwogICAgICAgIGxldCB1cmwgPSBgJHt0aGlzLmhvc3R9L3B1YmxpYy8/c2VydmljZT1BcHAuTW92LlNlYXJjaFZvZCZrZXk9JHtlbmNvZGVVUklDb21wb25lbnQodGhpcy5LRVkpfWA7CiAgICAgICAgbGV0IHJlc3AgPSBhd2FpdCBfZmV0Y2godXJsLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KTsKICAgICAgICBsZXQgdGV4dCA9IGF3YWl0IHJlc3AudGV4dCgpOwogICAgICAgIGlmICh0ZXh0LnN0YXJ0c1dpdGgoJ++7vycpKSB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMSk7CiAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKHRleHQpOwogICAgICAgIGxldCB2aWRlb3MgPSAoZGF0YS5EYXRhIHx8IFtdKS5tYXAoaSA9PiAoewogICAgICAgICAgICB0aXRsZTogaS52b2RfbmFtZSwKICAgICAgICAgICAgdXJsOiBgJHt0aGlzLmhvc3R9L3B1YmxpYy8/c2VydmljZT1BcHAuTW92LkdldE9ubGluZU12QnlJZCZ2b2RpZD0ke2kudm9kX2lkfWAsCiAgICAgICAgICAgIGRlc2M6IGkudm9kX3JlbWFya3MsCiAgICAgICAgICAgIHBpY191cmw6IGkudm9kX3BpYywKICAgICAgICAgICAgdm9kX3llYXI6IGkudm9kX3llYXIsCiAgICAgICAgICAgIGNvbnRlbnQ6IGkudm9kX2NvbnRlbnQKICAgICAgICB9KSk7CiAgICAgICAgcmV0dXJuIHNldFJlc3VsdCh2aWRlb3MpOwogICAgfSwKICAgIAogICAgbGF6eTogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBqeCA9IDA7CiAgICAgICAgbGV0IHVybCA9ICcnOwogICAgICAgIGxldCB1YSA9ICdjb20uZ2prai56eHlzZHEvMS4xLjAgKExpbnV4O0FuZHJvaWQgMTIpIEV4b1BsYXllckxpYi8yLjEyLjMnOwogICAgICAgIGxldCBpZCA9IHRoaXMuaW5wdXQ7CiAgICAgICAgaWYgKGlkLm1hdGNoKC9eaHR0cHM/OlwvXC8uKlwuKG0zdTh8bXA0fGZsdnxta3YpL2kpKSB7CiAgICAgICAgICAgIHVybCA9IGlkOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICBsZXQgcmVzcCA9IGF3YWl0IF9mZXRjaChgJHt0aGlzLmhvc3R9L3B1YmxpYy8/c2VydmljZT1BcHAuTW92LkdldE12SlhVcmxCeVVybCZ1cmw9JHtpZH1gLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KTsKICAgICAgICAgICAgICAgIGxldCB0ZXh0ID0gYXdhaXQgcmVzcC50ZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAodGV4dC5zdGFydHNXaXRoKCfvu78nKSkgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDEpOwogICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKHRleHQpOwogICAgICAgICAgICAgICAgbGV0IHJhd191cmwgPSBkYXRhLkRhdGEudXJsOwogICAgICAgICAgICAgICAgLy8g5bCd6K+V5L2/55SoQ3J5cHRvSlPov5vooYxBRVPop6Plr4YKICAgICAgICAgICAgICAgIGlmICh0aGlzLmtleSkgewogICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBrZXkgPSBDcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh0aGlzLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpdiA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHRoaXMuaXYpOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGVjcnlwdGVkVXJsID0gQ3J5cHRvSlMuQUVTLmRlY3J5cHQocmF3X3VybCwga2V5LCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU6IENyeXB0b0pTLm1vZGUuQ0JDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogQ3J5cHRvSlMucGFkLlBrY3M1CiAgICAgICAgICAgICAgICAgICAgICAgIH0pLnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTsKICAgICAgICAgICAgICAgICAgICAgICAgdXJsID0gZGVjcnlwdGVkVXJsICYmIGRlY3J5cHRlZFVybC5zdGFydHNXaXRoKCdodHRwJykgPyBkZWNyeXB0ZWRVcmwgOiB1cmw7CiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdBRVPop6Plr4blpLHotKU6JywgZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICBpZiAoLyg/Ond3d1wuaXFpeWl8dlwucXF8dlwueW91a3V8d3d3XC5tZ3R2fHd3d1wuYmlsaWJpbGkpXC5jb20vLnRlc3QoaWQpKSB7CiAgICAgICAgICAgICAgICAgICAgdXJsID0gaWQ7CiAgICAgICAgICAgICAgICAgICAganggPSAxOwogICAgICAgICAgICAgICAgICAgIHVhID0gTU9CSUxFX1VBOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHBhcnNlOiBqeCwKICAgICAgICAgICAgdXJsLAogICAgICAgICAgICBoZWFkZXI6IHsgJ1VzZXItQWdlbnQnOiB1YSB9CiAgICAgICAgfTsKICAgIH0KfTs= \ No newline at end of file From db6b9840cf2d8160fa699b8820d32aac1876ab7e Mon Sep 17 00:00:00 2001 From: eylinsir <283371717@qq.com> Date: Wed, 21 Jan 2026 18:46:25 +0800 Subject: [PATCH 57/99] Update files and directories --- ...1\220\350\201\232\345\220\210[\345\220\254].js" | 14 ++++++++++++++ ...5\220\351\237\263\344\271\220[\345\220\254].js" | 0 ...5\220\351\237\263\344\271\220[\345\220\254].js" | 0 ...261\263\345\205\224\351\237\263\344\271\220.js" | 0 .../\350\234\273\350\234\223FM[\345\220\254].js" | 0 5 files changed, 14 insertions(+) create mode 100644 "spider/js/\351\237\263\344\271\220\350\201\232\345\220\210[\345\220\254].js" rename "spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" => "spider/js_bad/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" (100%) rename "spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" => "spider/js_dr2_old/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" (100%) rename "spider/js_dr2/\347\261\263\345\205\224\351\237\263\344\271\220.js" => "spider/js_dr2_old/\347\261\263\345\205\224\351\237\263\344\271\220.js" (100%) rename "spider/js_dr2/\350\234\273\350\234\223FM[\345\220\254].js" => "spider/js_dr2_old/\350\234\273\350\234\223FM[\345\220\254].js" (100%) diff --git "a/spider/js/\351\237\263\344\271\220\350\201\232\345\220\210[\345\220\254].js" "b/spider/js/\351\237\263\344\271\220\350\201\232\345\220\210[\345\220\254].js" new file mode 100644 index 00000000..94802096 --- /dev/null +++ "b/spider/js/\351\237\263\344\271\220\350\201\232\345\220\210[\345\220\254].js" @@ -0,0 +1,14 @@ +/* +@header({ + searchable: 1, + filterable: 1, + quickSearch: 1, + title: '音乐聚合', + author: 'EylinSir', + '类型': '音乐', + logo: 'https://pic.5577.com/up/2021-9/202198191801219.png', + lang: 'ds' +}) +*/ + +dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICfpn7PkuZAnLAogICAgYXV0aG9yOiAnRXlsaW5TaXInLAogICAgdGl0bGU6ICfpn7PkuZDogZrlkIgnLAogICAgaG9zdDogJ2h0dHBzOi8vbXVzaWMtZGwuc2F5cXouY29tJywKICAgIGxvZ286ICdodHRwczovL3BpYy41NTc3LmNvbS91cC8yMDIxLTkvMjAyMTk4MTkxODAxMjE5LnBuZycsCiAgICBoZWFkZXJzOiB7CiAgICAgICAgJ1VzZXItQWdlbnQnOiBNT0JJTEVfVUEKICAgIH0sCiAgICBzZWFyY2hhYmxlOiAxLAogICAgcXVpY2tTZWFyY2g6IDEsCiAgICBmaWx0ZXJhYmxlOiAxLAogICAgdGltZW91dDogMTAwMDAsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAgY2xhc3NfbmFtZTogJ+e9keaYk+S6kemfs+S5kCZRUemfs+S5kCbphbfmiJHpn7PkuZAnLAogICAgY2xhc3NfdXJsOiAnbmV0ZWFzZSZxcSZrdXdvJywKICAgIHNlYXJjaFVybDogJy9hcGkvP3R5cGU9YWdncmVnYXRlU2VhcmNoJmtleXdvcmQ9KiombGltaXQ9MTAmcGFnZT0xJywKICAgIHR5cGVzOiBbCiAgICAgICAgeyBuYW1lOiAnSGktUmVz6Z+z6LSoJywgdmFsdWU6ICdmbGFjMjRiaXQnIH0sCiAgICAgICAgeyBuYW1lOiAn5peg5o2f6Z+z6LSoJywgdmFsdWU6ICdmbGFjJyB9LAogICAgICAgIHsgbmFtZTogJ+mrmOWTgemfs+i0qCcsIHZhbHVlOiAnMzIwaycgfSwKICAgICAgICB7IG5hbWU6ICfmoIflh4bpn7PotKgnLCB2YWx1ZTogJzEyOGsnIH0KICAgIF0sCiAgICBwbGF0Zm9ybXM6IFsnbmV0ZWFzZScsICdxcScsICdrdXdvJ10sCiAgICBwbGF0Zm9ybU5hbWVNYXA6IHsKICAgICAgICBuZXRlYXNlOiAn572R5piT5LqR6Z+z5LmQJywKICAgICAgICBxcTogJ1FR6Z+z5LmQJywKICAgICAgICBrdXdvOiAn6YW35oiR6Z+z5LmQJwogICAgfSwKCiAgICDkuIDnuqc6IGFzeW5jIGZ1bmN0aW9uICh0aWQsIHBnLCBmaWx0ZXIsIGV4dGVuZCkgewogICAgICAgIGxldCByZXN1bHQgPSBbXTsKICAgICAgICBsZXQgdGFyZ2V0UGxhdGZvcm1zID0gdGlkICYmIHRoaXMucGxhdGZvcm1zLmluY2x1ZGVzKHRpZCkgPyBbdGlkXSA6IHRoaXMucGxhdGZvcm1zOwogICAgICAgIGZvciAobGV0IHBsYXRmb3JtIG9mIHRhcmdldFBsYXRmb3JtcykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGF3YWl0IHJlcXVlc3QoYCR7dGhpcy5ob3N0fS9hcGkvP3NvdXJjZT0ke3BsYXRmb3JtfSZ0eXBlPXRvcGxpc3RzYCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSkpOwogICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goLi4uKGRhdGE/LmNvZGUgPT09IDIwMCAmJiBkYXRhLmRhdGE/Lmxpc3QgPyAKICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGEubGlzdC5tYXAoaXRlbSA9PiAoewogICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogaXRlbS5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IGAke3BsYXRmb3JtfV8ke2l0ZW0uaWR9YCwKICAgICAgICAgICAgICAgICAgICAgICAgZGVzYzogaXRlbS51cGRhdGVGcmVxdWVuY3ksCiAgICAgICAgICAgICAgICAgICAgICAgIHBpY191cmw6IGl0ZW0ucGljCiAgICAgICAgICAgICAgICAgICAgfSkpIDogW10pKTsKICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNldFJlc3VsdChyZXN1bHQpOwogICAgfSwKCiAgICDkuoznuqc6IGFzeW5jIGZ1bmN0aW9uICgpIHsKICAgICAgICBsZXQgW3BsYXRmb3JtLCByZWFsSWRdID0gdGhpcy5vcklkLnNwbGl0KCdfJyk7CiAgICAgICAgaWYgKCFwbGF0Zm9ybSB8fCAhcmVhbElkKSByZXR1cm4ge307CiAgICAgICAgbGV0IHNvbmdMaXN0ID0gW107CiAgICAgICAgbGV0IHZvZF9uYW1lID0gdGhpcy5vcklkOwogICAgICAgIGxldCB2b2RfZGVzYyA9ICcnOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCByZXMgPSBhd2FpdCByZXF1ZXN0KGAke3RoaXMuaG9zdH0vYXBpLz9zb3VyY2U9JHtwbGF0Zm9ybX0maWQ9JHtyZWFsSWR9JnR5cGU9dG9wbGlzdGAsIHsgaGVhZGVyczogdGhpcy5oZWFkZXJzIH0pOwogICAgICAgICAgICBsZXQgc29uZ0RhdGEgPSBKU09OLnBhcnNlKHJlcyk7CiAgICAgICAgICAgIGlmIChzb25nRGF0YT8uY29kZSA9PT0gMjAwICYmIHNvbmdEYXRhLmRhdGE/Lmxpc3QpIHsKICAgICAgICAgICAgICAgIHNvbmdMaXN0ID0gc29uZ0RhdGEuZGF0YS5saXN0OwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBsZXQgdG9wTGlzdHNSZXMgPSBhd2FpdCByZXF1ZXN0KGAke3RoaXMuaG9zdH0vYXBpLz9zb3VyY2U9JHtwbGF0Zm9ybX0mdHlwZT10b3BsaXN0c2AsIHsgaGVhZGVyczogdGhpcy5oZWFkZXJzIH0pOwogICAgICAgICAgICAgICAgICAgIGxldCB0b3BMaXN0c0RhdGEgPSBKU09OLnBhcnNlKHRvcExpc3RzUmVzKTsKICAgICAgICAgICAgICAgICAgICBsZXQgY3VycmVudExpc3QgPSB0b3BMaXN0c0RhdGE/LmNvZGUgPT09IDIwMCAmJiB0b3BMaXN0c0RhdGEuZGF0YT8ubGlzdCA/IAogICAgICAgICAgICAgICAgICAgICAgICB0b3BMaXN0c0RhdGEuZGF0YS5saXN0LmZpbmQoaXRlbSA9PiBpdGVtLmlkID09PSByZWFsSWQpIDogbnVsbDsKICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudExpc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdm9kX25hbWUgPSBjdXJyZW50TGlzdC5uYW1lOwogICAgICAgICAgICAgICAgICAgICAgICB2b2RfZGVzYyA9IGN1cnJlbnRMaXN0LnVwZGF0ZUZyZXF1ZW5jeSB8fCAnJzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJlcyA9IGF3YWl0IHJlcXVlc3QoYCR7dGhpcy5ob3N0fS9hcGkvP3NvdXJjZT0ke3BsYXRmb3JtfSZpZD0ke3JlYWxJZH0mdHlwZT1pbmZvYCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSk7CiAgICAgICAgICAgICAgICBzb25nRGF0YSA9IEpTT04ucGFyc2UocmVzKTsKICAgICAgICAgICAgICAgIGlmIChzb25nRGF0YT8uY29kZSAhPT0gMjAwIHx8ICFzb25nRGF0YS5kYXRhKSByZXR1cm4ge307CiAgICAgICAgICAgICAgICBzb25nTGlzdCA9IFtzb25nRGF0YS5kYXRhXTsKICAgICAgICAgICAgICAgIHZvZF9uYW1lID0gYCR7c29uZ0RhdGEuZGF0YS5uYW1lfSAtICR7c29uZ0RhdGEuZGF0YS5hcnRpc3R9YDsKICAgICAgICAgICAgICAgIHZvZF9kZXNjID0gc29uZ0RhdGEuZGF0YS5hbGJ1bSB8fCAnJzsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGVycikgewogICAgICAgICAgICBjb25zb2xlLmVycm9yKCfojrflj5bmlbDmja7lpLHotKU6JywgZXJyKTsKICAgICAgICAgICAgcmV0dXJuIHt9OwogICAgICAgIH0KCiAgICAgICAgaWYgKHZvZF9uYW1lID09PSB0aGlzLm9ySWQgJiYgc29uZ0xpc3QubGVuZ3RoKSB7CiAgICAgICAgICAgIHZvZF9uYW1lID0gYCR7c29uZ0xpc3RbMF0uYWxidW19IC0g5q2M5puy5YiX6KGoYDsKICAgICAgICAgICAgdm9kX2Rlc2MgPSBg5YWx5YyF5ZCrICR7c29uZ0xpc3QubGVuZ3RofSDpppbmrYzmm7JgOwogICAgICAgIH0KCiAgICAgICAgbGV0IHBsYXlfdXJsID0gc29uZ0xpc3QubWFwKHNvbmcgPT4gYCR7c29uZy5uYW1lfSAtICR7c29uZy5hcnRpc3R9JCR7cGxhdGZvcm19XyR7c29uZy5pZCB8fCByZWFsSWR9YCkuam9pbignIycpOwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHZvZF9pZDogdGhpcy5vcklkLAogICAgICAgICAgICB2b2RfbmFtZSwKICAgICAgICAgICAgdm9kX3BsYXlfZnJvbTogdGhpcy5wbGF0Zm9ybU5hbWVNYXBbcGxhdGZvcm1dLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHBsYXlfdXJsLAogICAgICAgICAgICB2b2RfZGVzYwogICAgICAgIH07CiAgICB9LAoKICAgIOaQnOe0ojogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCB1cmwgPSB0aGlzLnNlYXJjaFVybC5yZXBsYWNlKCcqKicsIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLktFWSkpOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGxldCBkYXRhID0gYXdhaXQgcmVxdWVzdCh1cmwsIHsKICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuaGVhZGVycywKICAgICAgICAgICAgICAgIHRpbWVvdXQ6IDEwMDAwIAogICAgICAgICAgICB9KTsKICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGRhdGEpOwogICAgICAgICAgICBpZiAoanNvbj8uY29kZSA9PT0gMjAwICYmIGpzb24/LmRhdGE/LnJlc3VsdHMpIHsKICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSBqc29uLmRhdGEucmVzdWx0cy5tYXAoaXRlbSA9PiAoewogICAgICAgICAgICAgICAgICAgIHRpdGxlOiBgJHtpdGVtLm5hbWV9IC0gJHtpdGVtLmFydGlzdH1gLAogICAgICAgICAgICAgICAgICAgIGRlc2M6IGAke2l0ZW0ucGxhdGZvcm0gPT09ICduZXRlYXNlJyA/ICfnvZHmmJPkupEnIDogaXRlbS5wbGF0Zm9ybSA9PT0gJ3FxJyA/ICdRUScgOiAn6YW35oiRJ33pn7PkuZAgLSAke2l0ZW0uYWxidW19YCwKICAgICAgICAgICAgICAgICAgICBwaWNfdXJsOiBpdGVtLnBpYywKICAgICAgICAgICAgICAgICAgICB1cmw6IGAke2l0ZW0ucGxhdGZvcm19XyR7aXRlbS5pZH1gCiAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICByZXR1cm4gc2V0UmVzdWx0KHJlc3VsdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICBjb25zb2xlLmVycm9yKCfmkJzntKLor7fmsYLplJnor686JywgZXJyb3IpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2V0UmVzdWx0KFtdKTsKICAgIH0sCgogICAgbGF6eTogYXN5bmMgZnVuY3Rpb24gKCkgewogICAgICAgIGxldCBbcGxhdGZvcm0sIHJlYWxJZF0gPSB0aGlzLmlucHV0LnNwbGl0KCdfJyk7CiAgICAgICAgaWYgKCFwbGF0Zm9ybSB8fCAhcmVhbElkKSB7CiAgICAgICAgICAgIHJldHVybiB7IHBhcnNlOiAwLCBwbGF5VXJsOiAnJywgdXJsOiBbXSwgaGVhZGVyOiB0aGlzLmhlYWRlcnMsIGxyYzogJycsIGNvdmVyOiAnJywgaGVpZ2h0OiA3MjAgfTsKICAgICAgICB9CiAgICAgICAgbGV0IGx5cmljID0gJyc7CiAgICAgICAgbGV0IGluZm9EYXRhID0ge307CiAgICAgICAgbGV0IFtseXJpY1JlcywgaW5mb1Jlc10gPSBhd2FpdCBQcm9taXNlLmFsbChbCiAgICAgICAgICAgIHJlcXVlc3QoYCR7dGhpcy5ob3N0fS9hcGkvP3NvdXJjZT0ke3BsYXRmb3JtfSZpZD0ke3JlYWxJZH0mdHlwZT1scmNgLCB7IGhlYWRlcnM6IHRoaXMuaGVhZGVycyB9KS5jYXRjaCgoKSA9PiAnJyksCiAgICAgICAgICAgIHJlcXVlc3QoYCR7dGhpcy5ob3N0fS9hcGkvP3NvdXJjZT0ke3BsYXRmb3JtfSZpZD0ke3JlYWxJZH0mdHlwZT1pbmZvYCwgeyBoZWFkZXJzOiB0aGlzLmhlYWRlcnMgfSkuY2F0Y2goKCkgPT4gJ3t9JykKICAgICAgICBdKTsKICAgICAgICBpZiAodHlwZW9mIGx5cmljUmVzID09PSAnc3RyaW5nJykgbHlyaWMgPSBseXJpY1JlczsKICAgICAgICB0cnkgewogICAgICAgICAgICBpbmZvRGF0YSA9IEpTT04ucGFyc2UoaW5mb1Jlcyk7CiAgICAgICAgfSBjYXRjaCAoZXJyKSB7fQogICAgICAgIGxldCBjb3ZlciA9IGluZm9EYXRhPy5jb2RlID09PSAyMDAgPyBpbmZvRGF0YS5kYXRhPy5waWMgfHwgJycgOiAnJzsKICAgICAgICBsZXQgdXJsID0gdGhpcy50eXBlcy5mbGF0TWFwKHR5cGUgPT4gW3R5cGUubmFtZSwgYCR7dGhpcy5ob3N0fS9hcGkvP3NvdXJjZT0ke3BsYXRmb3JtfSZpZD0ke3JlYWxJZH0mdHlwZT11cmwmYnI9JHt0eXBlLnZhbHVlfWBdKTsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICBwYXJzZTogMCwKICAgICAgICAgICAgcGxheVVybDogJycsCiAgICAgICAgICAgIHVybCwKICAgICAgICAgICAgaGVhZGVyOiB0aGlzLmhlYWRlcnMsCiAgICAgICAgICAgIGxyYzogbHlyaWMsCiAgICAgICAgICAgIGNvdmVyLAogICAgICAgICAgICBwaWM6IGNvdmVyLAogICAgICAgICAgICBoZWlnaHQ6IDcyMAogICAgICAgIH07CiAgICB9Cn07 \ No newline at end of file diff --git "a/spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" "b/spider/js_bad/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" similarity index 100% rename from "spider/js/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" rename to "spider/js_bad/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" diff --git "a/spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" "b/spider/js_dr2_old/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" similarity index 100% rename from "spider/js_dr2/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" rename to "spider/js_dr2_old/\347\247\215\345\255\220\351\237\263\344\271\220[\345\220\254].js" diff --git "a/spider/js_dr2/\347\261\263\345\205\224\351\237\263\344\271\220.js" "b/spider/js_dr2_old/\347\261\263\345\205\224\351\237\263\344\271\220.js" similarity index 100% rename from "spider/js_dr2/\347\261\263\345\205\224\351\237\263\344\271\220.js" rename to "spider/js_dr2_old/\347\261\263\345\205\224\351\237\263\344\271\220.js" diff --git "a/spider/js_dr2/\350\234\273\350\234\223FM[\345\220\254].js" "b/spider/js_dr2_old/\350\234\273\350\234\223FM[\345\220\254].js" similarity index 100% rename from "spider/js_dr2/\350\234\273\350\234\223FM[\345\220\254].js" rename to "spider/js_dr2_old/\350\234\273\350\234\223FM[\345\220\254].js" From d88ef787c99e751a303740e71268e06d781ee63b Mon Sep 17 00:00:00 2001 From: Taois Date: Wed, 21 Jan 2026 23:57:35 +0800 Subject: [PATCH 58/99] =?UTF-8?q?add:=20=E5=B0=9D=E8=AF=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0ds=E6=9C=AC=E5=9C=B0=E5=8C=85=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E4=B8=AD=E5=BF=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- controllers/web.js | 314 ++++++++++++++++++++++++++++++++++++++++++++- package.js | 12 +- package.json | 4 + package.py | 22 ++-- public/index.html | 3 +- 6 files changed, 342 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f8488af2..89cdbf6f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ nodejs作为服务端的drpy实现。全面升级异步写法 ### 常用超链接 * [本项目主页-免翻](https://github.com/hjdhnx/drpy-node) -* [最新DS本地包-适配皮卡丘](/gh/release) +* ~~[最新DS本地包-适配皮卡丘](/gh/release)~~ +* [DS本地包下载中心](/admin/download) * [接口文档](docs/apidoc.md) | [接口列表如定时任务](docs/apiList.md) | ~~[小猫影视-待对接T4](https://github.com/waifu-project/movie/pull/135)~~ * [代码质量评估工具说明](docs/codeCheck.md) | [DS项目代码评估报告](docs/codeCheckReport.md) diff --git a/controllers/web.js b/controllers/web.js index ce58537a..9327d27c 100644 --- a/controllers/web.js +++ b/controllers/web.js @@ -1,9 +1,92 @@ -import {readFileSync, existsSync} from 'fs'; +import {readFileSync, existsSync, readdirSync, statSync} from 'fs'; +import {createReadStream} from 'fs'; +import {execSync} from 'child_process'; import path from 'path'; +import {fileURLToPath} from 'url'; +import {createHash} from 'crypto'; import {ENV} from '../utils/env.js'; import COOKIE from '../utils/cookieManager.js'; +import {validateBasicAuth} from '../utils/api_validate.js'; const COOKIE_AUTH_CODE = process.env.COOKIE_AUTH_CODE || 'drpys'; +const IS_VERCEL = process.env.VERCEL; +const DOWNLOAD_AUTH_SECRET = process.env.DOWNLOAD_AUTH_SECRET || 'drpys_download_secret'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const projectRootDir = path.dirname(__dirname); + +const generateDownloadToken = (filename) => { + const timestamp = Date.now(); + const data = `${filename}-${timestamp}-${DOWNLOAD_AUTH_SECRET}`; + const token = createHash('md5').update(data).digest('hex'); + return `${token}-${timestamp}`; +}; + +const validateDownloadToken = (filename, token) => { + if (!token) return false; + const parts = token.split('-'); + if (parts.length < 2) return false; + const timestamp = parseInt(parts.pop()); + const hash = parts.join('-'); + const data = `${filename}-${timestamp}-${DOWNLOAD_AUTH_SECRET}`; + const expectedHash = createHash('md5').update(data).digest('hex'); + const now = Date.now(); + return hash === expectedHash && (now - timestamp) < 3600000; +}; + +const findLatestPackage = (projectDir, packageName) => { + try { + const parentDir = path.dirname(projectDir); + const files = readdirSync(parentDir); + + const isGreen = packageName.includes('-green'); + const ext = packageName.split('.').pop(); + const baseName = packageName.replace(/-green\.[^.]+$/, '').replace(/\.[^.]+$/, ''); + const pattern = new RegExp(`^${baseName.replace(/\./g, '\\.')}-\\d{8}${isGreen ? '-green' : ''}\\.${ext}`); + + console.log(`查找包: ${packageName}, 正则: ${pattern.source}, 父目录: ${parentDir}`); + console.log('目录中的文件:', files.filter(f => f.includes('drpy-node'))); + + const packageFiles = files + .filter(file => pattern.test(file)) + .map(file => { + const filePath = path.join(parentDir, file); + const stats = statSync(filePath); + return {file, filePath, mtime: stats.mtime}; + }) + .sort((a, b) => b.mtime - a.mtime); + + console.log('匹配到的文件:', packageFiles.map(f => f.file)); + return packageFiles.length > 0 ? packageFiles[0] : null; + } catch (error) { + console.error('查找包失败:', error.message); + return null; + } +}; + +const buildPackage = (packageName) => { + try { + let command = 'node package.js'; + if (packageName.includes('-green')) { + command += ' -g'; + } + if (packageName.includes('.zip')) { + command += ' -z'; + } + + console.log(`执行打包命令: ${command}, 目录: ${projectRootDir}`); + const output = execSync(command, {cwd: projectRootDir, stdio: 'pipe'}); + console.log('打包输出:', output.toString()); + const result = findLatestPackage(projectRootDir, packageName); + console.log('打包后查找结果:', result ? result.file : '未找到'); + return result; + } catch (error) { + console.error('打包失败:', error.message); + console.error('错误详情:', error.stdout?.toString(), error.stderr?.toString()); + throw error; + } +}; export default (fastify, options, done) => { fastify.get('/admin/encoder', async (request, reply) => { @@ -75,5 +158,234 @@ export default (fastify, options, done) => { } }); + fastify.get('/admin/download', { + preHandler: validateBasicAuth + }, async (request, reply) => { + try { + if (IS_VERCEL) { + return reply.code(403).send({ + success: false, + message: 'Vercel 环境不支持文件下载功能', + }); + } + + const projectName = path.basename(projectRootDir); + + const files = [ + {name: `${projectName}.7z`, desc: '7z 压缩包(标准版)'}, + {name: `${projectName}.zip`, desc: 'ZIP 压缩包(标准版)'}, + {name: `${projectName}-green.7z`, desc: '7z 压缩包(绿色版,不含[密]文件)'}, + {name: `${projectName}-green.zip`, desc: 'ZIP 压缩包(绿色版,不含[密]文件)'} + ]; + + const html = ` + + + + + + 下载 ${projectName} + + + +

    ${projectName} 下载中心

    +
    链接已复制到剪贴板
    +
    + ${files.map(file => { + const token = generateDownloadToken(file.name); + const downloadUrl = `/admin/download/${file.name}?auth=${token}`; + return ` +
    +
    + ${file.name} +
    ${file.desc}
    +
    +
    + 下载 + +
    +
    `; + }).join('')} +
    + + +`; + + reply.type('text/html').send(html); + } catch (error) { + console.error('下载页面加载失败:', error.message); + return reply.code(500).send({ + success: false, + message: '加载下载页面失败', + error: error.message, + }); + } + }); + + fastify.get('/admin/download/:filename', { + preHandler: async (request, reply) => { + const {auth} = request.query; + if (validateDownloadToken(request.params.filename, auth)) { + return; + } + const authHeader = request.headers.authorization; + if (!authHeader) { + reply.header('WWW-Authenticate', 'Basic'); + return reply.code(401).send('Authentication required'); + } + const base64Credentials = authHeader.split(' ')[1]; + const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8'); + const [username, password] = credentials.split(':'); + const validUsername = process.env.API_AUTH_NAME || ''; + const validPassword = process.env.API_AUTH_CODE || ''; + if (username === validUsername && password === validPassword) { + return; + } + reply.header('WWW-Authenticate', 'Basic'); + return reply.code(401).send('Invalid credentials'); + } + }, async (request, reply) => { + try { + if (IS_VERCEL) { + return reply.code(403).send({ + success: false, + message: 'Vercel 环境不支持文件下载功能', + }); + } + + const {filename} = request.params; + const projectName = path.basename(projectRootDir); + + const validFilenames = [ + `${projectName}.7z`, + `${projectName}.zip`, + `${projectName}-green.7z`, + `${projectName}-green.zip` + ]; + + if (!validFilenames.includes(filename)) { + return reply.code(400).send({ + success: false, + message: '无效的文件名', + }); + } + + let latestPackage = findLatestPackage(projectRootDir, filename); + + if (!latestPackage) { + console.log(`未找到 ${filename},开始打包...`); + latestPackage = buildPackage(filename); + if (!latestPackage) { + return reply.code(500).send({ + success: false, + message: '打包失败,无法创建压缩文件', + }); + } + } + + const fileStream = createReadStream(latestPackage.filePath); + const contentType = filename.endsWith('.zip') ? 'application/zip' : 'application/x-7z-compressed'; + reply.header('Content-Type', contentType); + reply.header('Content-Disposition', `attachment; filename="${encodeURIComponent(latestPackage.file)}"`); + return reply.send(fileStream); + } catch (error) { + console.error('下载文件失败:', error.message); + return reply.code(500).send({ + success: false, + message: '下载失败', + error: error.message, + }); + } + }); + done(); }; diff --git a/package.js b/package.js index 6489562d..9cc52648 100644 --- a/package.js +++ b/package.js @@ -37,7 +37,7 @@ const filterGreenFiles = (scriptDir) => { }; // 压缩目录 -const compressDirectory = (scriptDir, green) => { +const compressDirectory = (scriptDir, green, useZip) => { const currentDir = basename(scriptDir); const currentTime = new Date().toLocaleDateString('zh-CN', { year: 'numeric', @@ -45,12 +45,13 @@ const compressDirectory = (scriptDir, green) => { day: '2-digit' }).replace(/\//g, ''); const archiveSuffix = green ? '-green' : ''; - const archiveName = `${currentDir}-${currentTime}${archiveSuffix}.7z`; + const archiveExt = useZip ? '.zip' : '.7z'; + const archiveName = `${currentDir}-${currentTime}${archiveSuffix}${archiveExt}`; const parentDir = resolve(scriptDir, '..'); const archivePath = join(parentDir, archiveName); - // 构建 7z 命令 + // 构建压缩命令参数 const excludeParams = []; // 排除目录 @@ -77,7 +78,7 @@ const compressDirectory = (scriptDir, green) => { } // 构建命令,打包目录内容而不包含目录本身 - const command = `7z a "${archivePath}" "${join(scriptDir, '*')}" -r ${excludeParams.join(' ')}`; + const command = `7z a -t${useZip ? 'zip' : '7z'} "${archivePath}" "${join(scriptDir, '*')}" -r ${excludeParams.join(' ')}`; console.log(`构建的 7z 命令: ${command}`); try { @@ -95,8 +96,9 @@ const main = () => { // 简单解析命令行参数 const args = process.argv.slice(2); const green = args.includes('-g') || args.includes('--green'); + const useZip = args.includes('-z') || args.includes('--zip'); - compressDirectory(scriptDir, green); + compressDirectory(scriptDir, green, useZip); }; main(); diff --git a/package.json b/package.json index e350953d..e7e77108 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,12 @@ "node22-win": "chcp 65001 && node --trace-deprecation --experimental-sqlite index.js", "package": "python package.py", "package-green": "python package.py -g", + "package-zip": "python package.py -z", + "package-green-zip": "python package.py -g -z", "packageJS": "node package.js", "packageJS-green": "node package.js -g", + "packageJS-zip": "node package.js -z", + "packageJS-green-zip": "node package.js -g -z", "gzip-1": "node controllers/encoder.js json/十六万歌曲.json", "ungzip-1": "node controllers/decoder.js json/十六万歌曲.json.gz", "moontv": "node scripts/mjs/moontv.mjs 采集2025.json -p" diff --git a/package.py b/package.py index d34e7011..9949858f 100644 --- a/package.py +++ b/package.py @@ -45,13 +45,14 @@ def filter_green_files(script_dir): return green_files -def generate_archive_name(script_dir, green=False): +def generate_archive_name(script_dir, green=False, use_zip=False): """ 生成压缩包文件名 Args: script_dir (str): 脚本所在目录 green (bool): 是否为green模式 + use_zip (bool): 是否使用ZIP格式 Returns: str: 压缩包的完整路径 @@ -64,7 +65,8 @@ def generate_archive_name(script_dir, green=False): # 根据是否传入 green 参数生成压缩包文件名 archive_suffix = "-green" if green else "" - archive_name = f"{current_dir}-{current_time}{archive_suffix}.7z" + archive_ext = ".zip" if use_zip else ".7z" + archive_name = f"{current_dir}-{current_time}{archive_suffix}{archive_ext}" # 压缩包输出路径 (脚本所在目录的外面) parent_dir = os.path.abspath(os.path.join(script_dir, "..")) @@ -108,7 +110,7 @@ def build_exclude_params(script_dir, green=False): return exclude_params -def execute_compression(archive_path, script_dir, exclude_params): +def execute_compression(archive_path, script_dir, exclude_params, use_zip=False): """ 执行7z压缩命令 @@ -116,9 +118,11 @@ def execute_compression(archive_path, script_dir, exclude_params): archive_path (str): 压缩包输出路径 script_dir (str): 脚本所在目录 exclude_params (list): 排除参数列表 + use_zip (bool): 是否使用ZIP格式 """ # 构建命令,打包目录内容而不包含目录本身 - command = f"7z a \"{archive_path}\" \"{script_dir}\\*\" " + " ".join(exclude_params) + archive_type = "zip" if use_zip else "7z" + command = f"7z a -t{archive_type} \"{archive_path}\" \"{script_dir}\\*\" " + " ".join(exclude_params) # 打印构建的命令进行调试 print(f"构建的 7z 命令: {command}") @@ -131,22 +135,23 @@ def execute_compression(archive_path, script_dir, exclude_params): print(f"压缩失败: {e}") -def compress_directory(script_dir, green=False): +def compress_directory(script_dir, green=False, use_zip=False): """ 压缩目录为7z包 Args: script_dir (str): 要压缩的目录路径 green (bool): 是否启用green模式,筛选带[密]的文件 + use_zip (bool): 是否使用ZIP格式 """ # 生成压缩包文件名和路径 - archive_path = generate_archive_name(script_dir, green) + archive_path = generate_archive_name(script_dir, green, use_zip) # 构建排除参数 exclude_params = build_exclude_params(script_dir, green) # 执行压缩 - execute_compression(archive_path, script_dir, exclude_params) + execute_compression(archive_path, script_dir, exclude_params, use_zip) if __name__ == "__main__": @@ -156,7 +161,8 @@ def compress_directory(script_dir, green=False): # 解析命令行参数 parser = argparse.ArgumentParser(description="压缩当前目录为 7z 包,支持可选参数。") parser.add_argument('-g', '--green', action='store_true', help="启用 green 模式,筛选 js 目录下所有带 [密] 的文件。") + parser.add_argument('-z', '--zip', action='store_true', help="使用 ZIP 格式打包,默认使用 7z 格式。") args = parser.parse_args() # 调用压缩函数 - compress_directory(script_dir, green=args.green) + compress_directory(script_dir, green=args.green, use_zip=args.zip) diff --git a/public/index.html b/public/index.html index 41ed026e..a580710f 100644 --- a/public/index.html +++ b/public/index.html @@ -14,7 +14,8 @@

    drpyS(drpy-node)

    常用超链接