diff --git a/lib/alist.js b/lib/alist.js deleted file mode 100644 index ae9bd448..00000000 --- a/lib/alist.js +++ /dev/null @@ -1,819 +0,0 @@ -// import _ from 'https://underscorejs.org/underscore-esm-min.js' -// import {distance} from 'https://unpkg.com/fastest-levenshtein@1.0.16/esm/mod.js' -import {distance} from './mod.js' -import {sortListByCN} from './sortName.js' - -/** - * alist js - * 配置设置 {"key":"Alist","name":"Alist","type":3,"api":"http://xxx.com/alist.js","searchable":0,"quickSearch":0,"filterable":0,"ext":"http://xxx.com/alist.json"} - * alist.json [{ - name:'名称', - server:'地址', - startPage:'/', //启动文件夹 - showAll: false , //是否显示全部文件,默认false只显示 音视频和文件夹 - search: true, // 启用小雅的搜索,搜索只会搜第一个开启此开关的磁盘 - params:{ //对应文件夹参数 如设置对应文件夹的密码 - '/abc':{ password : '123' }, - '/abc/abc':{ password : '123' }, - } - }] - * 提示 想要加载文件夹里面全部视频到详情(看剧可以自动播放下一集支持历史记录) - * 需要改软件才能支持,,建议长按文件夹时添加判断 tag == folder 时跳转 DetailActivity - */ -String.prototype.rstrip = function (chars) { - let regex = new RegExp(chars + "$"); - return this.replace(regex, ""); -}; -var showMode = 'single'; -var searchDriver = ''; -var limit_search_show = 200; -var search_type = ''; -var detail_order = 'name'; -var playRaw = 1; // 播放直链获取,默认0直接拼接/d 填1可以获取阿里oss链接。注意,有时效性 -const request_timeout = 5000; -const VERSION = 'alist v2/v3 20221223'; -const UA = 'Mozilla/5.0'; //默认请求ua -/** - * 打印日志 - * @param any 任意变量 - */ -function print(any){ - any = any||''; - if(typeof(any)=='object'&&Object.keys(any).length>0){ - try { - any = JSON.stringify(any); - console.log(any); - }catch (e) { - // console.log('print:'+e.message); - console.log(typeof(any)+':'+any.length); - } - }else if(typeof(any)=='object'&&Object.keys(any).length<1){ - console.log('null object'); - }else{ - console.log(any); - } -} - -/*** js自封装的方法 ***/ - -/** - * 获取链接的host(带http协议的完整链接) - * @param url 任意一个正常完整的Url,自动提取根 - * @returns {string} - */ -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 -} - -const http = function (url, options = {}) { - if(options.method ==='POST' && options.data){ - options.body = JSON.stringify(options.data); - options.headers = Object.assign({'content-type':'application/json'}, options.headers); - } - options.timeout = request_timeout; - if(!options.headers){ - options.headers = {}; - } - let keys = Object.keys(options.headers).map(it=>it.toLowerCase()); - if(!keys.includes('referer')){ - options.headers['Referer'] = getHome(url); - } - if(!keys.includes('user-agent')){ - options.headers['User-Agent'] = UA; - } - console.log(JSON.stringify(options.headers)); - try { - const res = req(url, options); - // if(options.headers['Authorization']){ - // console.log(res.content); - // } - res.json = () => res&&res.content ? JSON.parse(res.content) : null; - res.text = () => res&&res.content ? res.content:''; - return res - }catch (e) { - return { - json() { - return null - }, text() { - return '' - } - } - } -}; -["get", "post"].forEach(method => { - http[method] = function (url, options = {}) { - return http(url, Object.assign(options, {method: method.toUpperCase()})); - } -}); - -const __drives = {}; - -function isMedia(file){ - return /\.(dff|dsf|mp3|aac|wav|wma|cda|flac|m4a|mid|mka|mp2|mpa|mpc|ape|ofr|ogg|ra|wv|tta|ac3|dts|tak|webm|wmv|mpeg|mov|ram|swf|mp4|avi|rm|rmvb|flv|mpg|mkv|m3u8|ts|3gp|asf)$/.test(file.toLowerCase()); -} - -function get_drives_path(tid) { - const index = tid.indexOf('$'); - const name = tid.substring(0, index); - const path = tid.substring(index + 1); - return { drives: get_drives(name), path }; -} - -function get_drives(name) { - const { settings, api, server,headers } = __drives[name]; - if (settings.v3 == null) { //获取 设置 - settings.v3 = false; - const data = http.get(server + '/api/public/settings',{headers:headers}).json().data; - if (Array.isArray(data)) { - settings.title = data.find(x => x.key === 'title')?.value; - settings.v3 = false; - settings.version = data.find(x => x.key === 'version')?.value; - settings.enableSearch = data.find(x => x.key === 'enable search')?.value === 'true'; - } else { - settings.title = data.title; - settings.v3 = true; - settings.version = data.version; - settings.enableSearch = false; //v3 没有找到 搜索配置 - } - //不同版本 接口不一样 - api.path = settings.v3 ? '/api/fs/list' : '/api/public/path'; - api.file = settings.v3 ? '/api/fs/get' : '/api/public/path'; - api.search = settings.v3 ? '/api/public/search' : '/api/public/search'; - } - return __drives[name] -} - -function init(ext) { - console.log("当前版本号:"+VERSION); - let data; - if (typeof ext == 'object'){ - data = ext; - print('alist ext:object'); - } else if (typeof ext == 'string') { - if (ext.startsWith('http')) { - let alist_data = ext.split(';'); - let alist_data_url = alist_data[0]; - limit_search_show = alist_data.length>1?Number(alist_data[1])||limit_search_show:limit_search_show; - search_type = alist_data.length>2?alist_data[2]:search_type; - print(alist_data_url); - data = http.get(alist_data_url).json(); // .map(it=>{it.name='🙋丫仙女';return it}) - } else { - print('alist ext:json string'); - data = JSON.parse(ext); - } - } - - // print(data); // 测试证明壳子标题支持emoji,是http请求源码不支持emoji - let drives = []; - if(Array.isArray(data) && data.length > 0 && data[0].hasOwnProperty('server') && data[0].hasOwnProperty('name')){ - drives = data; - }else if(!Array.isArray(data)&&data.hasOwnProperty('drives')&&Array.isArray(data.drives)){ - drives = data.drives.filter(it=>(it.type&&it.type==='alist')||!it.type); - } - print(drives); - searchDriver = (drives.find(x=>x.search)||{}).name||''; - if(!searchDriver && drives.length > 0){ - searchDriver = drives[0].name; - } - print(searchDriver); - drives.forEach(item => { - let _path_param = []; - if(item.params){ - _path_param = Object.keys(item.params); - // 升序排列 - _path_param.sort((a,b)=>(a.length-b.length)); - } - if(item.password){ - let pwdObj = { - password: item.password - }; - if(!item.params){ - item.params = {'/':pwdObj}; - }else{ - item.params['/'] = pwdObj; - } - _path_param.unshift('/'); - } - __drives[item.name] = { - name: item.name, - server: item.server.endsWith("/") ? item.server.rstrip("/") : item.server, - startPage: item.startPage || '/', //首页 - showAll: item.showAll === true, //默认只显示 视频和文件夹,如果想显示全部 showAll 设置true - search: !!item.search, //是否支持搜索,只有小丫的可以,多个可搜索只取最前面的一个 - params: item.params || {}, - _path_param: _path_param, - settings: {}, - api: {}, - headers:item.headers||{}, - getParams(path) { - const key = this._path_param.find(x => path.startsWith(x)); - return Object.assign({}, this.params[key], { path }); - }, - getPath(path) { - const res = http.post(this.server + this.api.path, { data: this.getParams(path),headers:this.headers }).json(); - // console.log(res); - try { - return this.settings.v3 ? res.data.content : res.data.files - }catch (e) { - console.log(`getPath发生错误:${e.message}`); - console.log(JSON.stringify(res)); - return [{name:'error',value:JSON.stringify(res)}] - } - }, - getFile(path) { - let raw_url = this.server+'/d'+path; - raw_url = encodeURI(raw_url); - let data = {raw_url:raw_url,raw_url1:raw_url}; - if(playRaw===1){ - try { - const res = http.post(this.server + this.api.file, { data: this.getParams(path),headers:this.headers }).json(); - data = this.settings.v3 ? res.data : res.data.files[0]; - if (!this.settings.v3) { - data.raw_url = data.url; //v2 的url和v3不一样 - } - data.raw_url1 = raw_url; - return data - }catch (e) { - return data - } - }else{ - return data - } - }, - isFolder(data) { return data.type === 1 }, - isVideo(data) { //判断是否是 视频文件 - // return this.settings.v3 ? data.type === 2 : data.type === 3 - // 增加音乐识别 视频,其他,音频 - return this.settings.v3 ? (data.type === 2||data.type===0||data.type===3) : (data.type === 3||data.type===0||data.type === 4) - }, - is_subt(data) { - if (data.type === 1) { - return false; - } - const ext = /\.(srt|ass|scc|stl|ttml)$/; // [".srt", ".ass", ".scc", ".stl", ".ttml"]; - // return ext.some(x => data.name.endsWith(x)); - return ext.test(data.name); - }, - getPic(data) { - let pic = this.settings.v3 ? data.thumb : data.thumbnail; - return pic || (this.isFolder(data) ? "http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png" : ''); - }, - getTime(data,isStandard) { - isStandard = isStandard||false; - try { - let tTime = data.updated_at || data.time_str || data.modified || ""; - let date = ''; - if(tTime){ - tTime = tTime.split("T"); - date = tTime[0]; - if(isStandard){ - date = date.replace(/-/g,"/"); - } - tTime = tTime[1].split(/Z|\./); - date += " " + tTime[0]; - } - return date; - }catch (e) { - // print(e.message); - // print(data); - return '' - } - }, - } - } - ); - print('init执行完毕'); -} - -function home(filter) { - let classes = Object.keys(__drives).map(key => ({ - type_id: `${key}$${__drives[key].startPage}`, - type_name: key, - type_flag: '1', - })); - let filter_dict = {}; - let filters = [{'key': 'order', 'name': '排序', 'value': [{'n': '名称⬆️', 'v': 'vod_name_asc'}, {'n': '名称⬇️', 'v': 'vod_name_desc'}, - {'n': '中英⬆️', 'v': 'vod_cn_asc'}, {'n': '中英⬇️', 'v': 'vod_cn_desc'}, - {'n': '时间⬆️', 'v': 'vod_time_asc'}, {'n': '时间⬇️', 'v': 'vod_time_desc'}, - {'n': '大小⬆️', 'v': 'vod_size_asc'}, {'n': '大小⬇️', 'v': 'vod_size_desc'},{'n': '无', 'v': 'none'}]}, - {'key': 'show', 'name': '播放展示', 'value': [{'n': '单集', 'v': 'single'},{'n': '全集', 'v': 'all'}]} - ]; - classes.forEach(it=>{ - filter_dict[it.type_id] = filters; - }); - print("----home----"); - print(classes); - return JSON.stringify({ 'class': classes,'filters': filter_dict}); -} - -function homeVod(params) { - let _post_data = {"pageNum":0,"pageSize":100}; - let _post_url = 'https://pbaccess.video.qq.com/trpc.videosearch.hot_rank.HotRankServantHttp/HotRankHttp'; - let data = http.post(_post_url,{ data: _post_data }).json(); - let _list = []; - try { - data = data['data']['navItemList'][0]['hotRankResult']['rankItemList']; - // print(data); - data.forEach(it=>{ - _list.push({ - vod_name:it.title, - vod_id:'msearch:'+it.title, - vod_pic:'https://avatars.githubusercontent.com/u/97389433?s=120&v=4', - vod_remarks:it.changeOrder, - }); - }); - }catch (e) { - print('Alist获取首页推荐发送错误:'+e.message); - } - return JSON.stringify({ 'list': _list }); -} - -function category(tid, pg, filter, extend) { - let orid = tid.replace(/#all#|#search#/g,''); - let { drives, path } = get_drives_path(orid); - const id = orid.endsWith('/') ? orid : orid + '/'; - const list = drives.getPath(path); - let subList = []; - let vodFiles = []; - let allList = []; - let fl = filter?extend:{}; - if(fl.show){ - showMode = fl.show; - } - list.forEach(item => { - if(item.name!=='error') { - if (drives.is_subt(item)) { - subList.push(item.name); - } - if (!drives.showAll && !drives.isFolder(item) && !drives.isVideo(item)) { - return //只显示视频文件和文件夹 - } - let vod_time = drives.getTime(item); - let vod_size = get_size(item.size); - let remark = vod_time.split(' ')[0].substr(3) + '\t' + vod_size; - let vod_id = id + item.name + (drives.isFolder(item) ? '/' : ''); - if (showMode === 'all') { - vod_id += '#all#'; - } - print(vod_id); - const vod = { - 'vod_id': vod_id, - 'vod_name': item.name.replaceAll("$", "").replaceAll("#", ""), - 'vod_pic': drives.getPic(item), - 'vod_time': vod_time, - 'vod_size': item.size, - 'vod_tag': drives.isFolder(item) ? 'folder' : 'file', - 'vod_remarks': drives.isFolder(item) ? remark + ' 文件夹' : remark - }; - if (drives.isVideo(item)) { - vodFiles.push(vod); - } - allList.push(vod); - }else{ - console.log(item); - const vod = { - vod_name: item.value, - vod_id: 'no_data', - vod_remarks: '不要点,会崩的', - vod_pic: 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/404.jpg' - } - allList.push(vod); - } - }); - - if (vodFiles.length === 1 && subList.length > 0) { //只有一个视频 一个或者多个字幕 取相似度最高的 - // let sub = subList.length === 1 ? subList[0] : _.chain(allList).sortBy(x => (x.includes('chs') ? 100 : 0) + levenshteinDistance(x, vodFiles[0].vod_name)).last().value(); - let sub; // 字幕文件名称 - if(subList.length === 1){ - sub = subList[0]; - }else { - let subs = JSON.parse(JSON.stringify(subList)); - subs.sort((a,b)=>{ - // chs是简体中文字幕 - let a_similar = (a.includes('chs') ? 100 : 0) + levenshteinDistance(a, vodFiles[0].vod_name); - let b_similar = (b.includes('chs') ? 100 : 0) + levenshteinDistance(b, vodFiles[0].vod_name); - if(a_similar>b_similar) { // 按相似度正序排列 - return 1; - }else{ //否则,位置不变 - return -1; - } - }); - sub = subs.slice(-1)[0]; - } - vodFiles[0].vod_id += "@@@" + sub; - // vodFiles[0].vod_remarks += " 有字幕"; - vodFiles[0].vod_remarks += "🏷️"; - } else { - vodFiles.forEach(item => { - const lh = 0; - let sub; - subList.forEach(s => { - //编辑距离相似度 - const l = levenshteinDistance(s, item.vod_name); - if (l > 60 && l > lh) { - sub = s; - } - }); - if (sub) { - item.vod_id += "@@@" + sub; - // item.vod_remarks += " 有字幕"; - item.vod_remarks += "🏷️"; - } - }); - } - - if(fl.order){ - // print(fl.order); - let key = fl.order.split('_').slice(0,-1).join('_'); - let order = fl.order.split('_').slice(-1)[0]; - print(`排序key:${key},排序order:${order}`); - if(key.includes('name')){ - detail_order = 'name'; - allList = sortListByName(allList,key,order); - }else if(key.includes('cn')){ - detail_order = 'cn'; - allList = sortListByCN(allList,'vod_name',order); - }else if(key.includes('time')){ - detail_order = 'time'; - allList = sortListByTime(allList,key,order); - }else if(key.includes('size')){ - detail_order = 'size'; - allList = sortListBySize(allList,key,order); - }else if(fl.order.includes('none')){ - detail_order = 'none'; - print('不排序'); - } - }else{ - // 没传order是其他地方调用的,自动按名称正序排序方便追剧,如果传了none进去就不排序,假装云盘里本身文件顺序是正常的 - if(detail_order!=='none'){ - allList = sortListByName(allList,'vod_name','asc'); - } - } - - print("----category----"+`tid:${tid},detail_order:${detail_order},showMode:${showMode}`); - // print(allList); - return JSON.stringify({ - 'page': 1, - 'pagecount': 1, - 'limit': allList.length, - 'total': allList.length, - 'list': allList, - }); -} - -function getAll(otid,tid,drives,path){ - try { - const content = category(tid, null, false, null); - const isFile = isMedia(otid.replace(/#all#|#search#/g,'').split('@@@')[0]); - const { list } = JSON.parse(content); - let vod_play_url = []; - list.forEach(x => { - if (x.vod_tag === 'file'){ - let vid = x.vod_id.replace(/#all#|#search#/g,''); - vod_play_url.push(`${x.vod_name}$${vid.substring(vid.indexOf('$') + 1)}`); - } - }); - const pl = path.split("/").filter(it=>it); - let vod_name = pl[pl.length - 1] || drives.name; - if(vod_name === drives.name){ - print(pl); - } - if(otid.includes('#search#')){ - vod_name+='[搜]'; - } - let vod = { - // vod_id: tid, - vod_id: otid, - vod_name: vod_name, - type_name: "文件夹", - vod_pic: "https://avatars.githubusercontent.com/u/97389433?s=120&v=4", - vod_content: tid, - vod_tag: 'folder', - vod_play_from: drives.name, - vod_play_url: vod_play_url.join('#'), - vod_remarks: drives.settings.title, - } - print("----detail1----"); - print(vod); - return JSON.stringify({ 'list': [vod] }); - }catch (e) { - print(e.message); - let list = [{vod_name:'无数据,防无限请求',type_name: "文件夹",vod_id:'no_data',vod_remarks:'不要点,会崩的',vod_pic:'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/static/img/404.jpg',vod_actor:e.message,vod_director: tid,vod_content: otid}]; - return JSON.stringify({ 'list': list }); - } -} - -function detail(tid) { - let isSearch = tid.includes('#search#'); - let isAll = tid.includes('#all#'); - let otid = tid; - tid = tid.replace(/#all#|#search#/g,''); - let isFile = isMedia(tid.split('@@@')[0]); - print(`isFile:${tid}?${isFile}`); - let { drives, path } = get_drives_path(tid); - print(`drives:${drives},path:${path},`); - if (path.endsWith("/")) { //长按文件夹可以 加载里面全部视频到详情 - return getAll(otid,tid,drives,path); - } else { - if(isSearch&&!isFile){ // 搜索结果 当前目录获取所有文件 - return getAll(otid,tid,drives,path); - }else if(isAll){ // 上级目录获取所有文件 不管是搜索还是分类,只要不是 搜索到的文件夹,且展示模式为全部,都获取上级目录的所有文件 - // 是文件就取上级目录 - let new_tid; - if(isFile){ - new_tid = tid.split('/').slice(0,-1).join('/')+'/'; - }else{ - new_tid = tid; - } - print(`全集模式 tid:${tid}=>tid:${new_tid}`); - let { drives, path } = get_drives_path(new_tid); - return getAll(otid,new_tid,drives,path); - } else if(isFile){ // 单文件进入 - let paths = path.split("@@@"); - let vod_name = paths[0].substring(paths[0].lastIndexOf("/") + 1); - let vod_title = vod_name; - if(otid.includes('#search#')){ - vod_title+='[搜]'; - } - let vod = { - vod_id: otid, - vod_name: vod_title, - type_name: "文件", - vod_pic: "https://avatars.githubusercontent.com/u/97389433?s=120&v=4", - vod_content: tid, - vod_play_from: drives.name, - vod_play_url: vod_name + "$" + path, - vod_remarks: drives.settings.title, - }; - print("----detail2----"); - print(vod); - return JSON.stringify({ - 'list': [vod] - }); - }else{ - return JSON.stringify({ - 'list': [] - }); - } - } -} - -function play(flag, id, flags) { - const drives = get_drives(flag); - const urls = id.split("@@@"); // @@@ 分割前是 相对文件path,分割后是字幕文件 - let vod = { - 'parse': 0, - 'playUrl': '', - // 'url': drives.getFile(urls[0]).raw_url+'#.m3u8' // 加 # 没法播放 - 'url': drives.getFile(urls[0]).raw_url - }; - if (urls.length >= 2) { - const path = urls[0].substring(0, urls[0].lastIndexOf('/') + 1); - vod.subt = drives.getFile(path + urls[1]).raw_url1; - } - print("----play----"); - print(vod); - return JSON.stringify(vod); -} - -function search(wd, quick) { - print(__drives); - print('可搜索的alist驱动:'+searchDriver); - if(!searchDriver||!wd){ - return JSON.stringify({ - 'list': [] - }); - }else{ - let driver = __drives[searchDriver]; - wd = wd.split(' ').filter(it=>it.trim()).join('+'); - print(driver); - let surl = driver.server + '/search?box='+wd+'&url='; - if(search_type){ - surl+='&type='+search_type; - } - print('搜索链接:'+surl); - let html = http.get(surl).text(); - let lists = []; - try { - lists = pdfa(html,'div&&ul&&a'); - }catch (e) {} - print(`搜索结果数:${lists.length},搜索结果显示数量限制:${limit_search_show}`); - let vods = []; - let excludeReg = /\.(pdf|epub|mobi|txt|doc|lrc)$/; // 过滤后缀文件 - let cnt = 0; - lists.forEach(it=>{ - let vhref = pdfh(it,'a&&href'); - if(vhref){ - vhref = unescape(vhref); - } - if(excludeReg.test(vhref)){ - return; //跳过本次循环 - } - if(cnt < limit_search_show){ - print(vhref); - } - cnt ++; - let vid = searchDriver+'$'+vhref+'#search#'; - if(showMode==='all'){ - vid+='#all#'; - } - vods.push({ - vod_name:pdfh(it,'a&&Text'), - vod_id:vid, - vod_tag: isMedia(vhref) ? 'file' : 'folder', - vod_pic:'http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png', - vod_remarks:searchDriver - }); - }); - // 截取搜索结果 - vods = vods.slice(0,limit_search_show); - print(vods); - return JSON.stringify({ - 'list': vods - }); - } -} - -function get_size(sz) { - if (sz <= 0) { - return ""; - } - let filesize = ""; - if (sz > 1024 * 1024 * 1024 * 1024.0) { - sz /= (1024 * 1024 * 1024 * 1024.0); - filesize = "TB"; - } else if (sz > 1024 * 1024 * 1024.0) { - sz /= (1024 * 1024 * 1024.0); - filesize = "GB"; - } else if (sz > 1024 * 1024.0) { - sz /= (1024 * 1024.0); - filesize = "MB"; - } else if( sz > 1024.0){ - sz /= 1024.0; - filesize = "KB"; - }else{ - filesize = "B"; - } - // 转成字符串 - let sizeStr = sz.toFixed(2) + filesize, - // 获取小数点处的索引 - index = sizeStr.indexOf("."), - // 获取小数点后两位的值 - dou = sizeStr.substr(index + 1, 2); - if (dou === "00") { - return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2); - }else{ - return sizeStr; - } -} - -// 相似度获取 -function levenshteinDistance(str1, str2) { - return 100 - 100 * distance(str1, str2) / Math.max(str1.length, str2.length); -} - -/** - * 自然排序 - * ["第1集","第10集","第20集","第2集","1","2","10","12","23","01","02"].sort(naturalSort()) - * @param options {{key,caseSensitive, order: string}} - */ -function naturalSort(options) { - if (!options) { - options = {}; - } - - return function (a, b) { - if(options.key){ - a = a[options.key]; - b = b[options.key]; - } - var EQUAL = 0; - var GREATER = (options.order === 'desc' ? - -1 : - 1 - ); - var SMALLER = -GREATER; - - var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi; - var sre = /(^[ ]*|[ ]*$)/g; - var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/; - var hre = /^0x[0-9a-f]+$/i; - var ore = /^0/; - - var normalize = function normalize(value) { - var string = '' + value; - return (options.caseSensitive ? - string : - string.toLowerCase() - ); - }; - - // Normalize values to strings - var x = normalize(a).replace(sre, '') || ''; - var y = normalize(b).replace(sre, '') || ''; - - // chunk/tokenize - var xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - var yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'); - - // Return immediately if at least one of the values is empty. - if (!x && !y) return EQUAL; - if (!x && y) return GREATER; - if (x && !y) return SMALLER; - - // numeric, hex or date detection - var xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)); - var yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null; - var oFxNcL, oFyNcL; - - // first try and sort Hex codes or Dates - if (yD) { - if (xD < yD) return SMALLER; - else if (xD > yD) return GREATER; - } - - // natural sorting through split numeric strings and default strings - for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { - - // find floats not starting with '0', string or 0 if not defined (Clint Priest) - oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; - oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; - - // handle numeric vs string comparison - number < string - (Kyle Adams) - if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? GREATER : SMALLER; - - // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' - else if (typeof oFxNcL !== typeof oFyNcL) { - oFxNcL += ''; - oFyNcL += ''; - } - if (oFxNcL < oFyNcL) return SMALLER; - if (oFxNcL > oFyNcL) return GREATER; - } - return EQUAL; - }; -} -// 完整名称排序 -const sortListByName = (vodList,key,order) => { - if(!key){ - return vodList - } - order = order||'asc'; // 默认正序 - // 排序键,顺序,区分大小写 - return vodList.sort(naturalSort({key: key, order: order,caseSensitive:true})) -}; - -const getTimeInt = (timeStr) => { - return (new Date(timeStr)).getTime(); -}; - -// 时间 -const sortListByTime = (vodList,key,order) => { - if (!key) { - return vodList - } - let ASCarr = vodList.sort((a, b) => { - a = a[key]; - b = b[key]; - return getTimeInt(a) - getTimeInt(b); - }); - if(order==='desc'){ - ASCarr.reverse(); - } - return ASCarr -}; - -// 大小 -const sortListBySize = (vodList,key,order) => { - if (!key) { - return vodList - } - let ASCarr = vodList.sort((a, b) => { - a = a[key]; - b = b[key]; - return (Number(a) || 0) - (Number(b) || 0); - }); - if(order==='desc'){ - ASCarr.reverse(); - } - return ASCarr -}; - -// 导出函数对象 -export default { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search -} \ No newline at end of file diff --git a/lib/alist.min.js b/lib/alist.min.js deleted file mode 100644 index ddd4adf5..00000000 --- a/lib/alist.min.js +++ /dev/null @@ -1 +0,0 @@ -import{distance}from"./mod.js";import{sortListByCN}from"./sortName.js";String.prototype.rstrip=function(chars){let regex=new RegExp(chars+"$");return this.replace(regex,"")};var showMode="single";var searchDriver="";var limit_search_show=200;var search_type="";var detail_order="name";var playRaw=1;const request_timeout=5e3;const VERSION="alist v2/v3 20221223";const UA="Mozilla/5.0";function print(any){any=any||"";if(typeof any=="object"&&Object.keys(any).length>0){try{any=JSON.stringify(any);console.log(any)}catch(e){console.log(typeof any+":"+any.length)}}else if(typeof any=="object"&&Object.keys(any).length<1){console.log("null object")}else{console.log(any)}}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}const http=function(url,options={}){if(options.method==="POST"&&options.data){options.body=JSON.stringify(options.data);options.headers=Object.assign({"content-type":"application/json"},options.headers)}options.timeout=request_timeout;if(!options.headers){options.headers={}}let keys=Object.keys(options.headers).map(it=>it.toLowerCase());if(!keys.includes("referer")){options.headers["Referer"]=getHome(url)}if(!keys.includes("user-agent")){options.headers["User-Agent"]=UA}try{const res=req(url,options);res.json=()=>res&&res.content?JSON.parse(res.content):null;res.text=()=>res&&res.content?res.content:"";return res}catch(e){return{json(){return null},text(){return""}}}};["get","post"].forEach(method=>{http[method]=function(url,options={}){return http(url,Object.assign(options,{method:method.toUpperCase()}))}});const __drives={};function isMedia(file){return/\.(dff|dsf|mp3|aac|wav|wma|cda|flac|m4a|mid|mka|mp2|mpa|mpc|ape|ofr|ogg|ra|wv|tta|ac3|dts|tak|webm|wmv|mpeg|mov|ram|swf|mp4|avi|rm|rmvb|flv|mpg|mkv|m3u8|ts|3gp|asf)$/.test(file.toLowerCase())}function get_drives_path(tid){const index=tid.indexOf("$");const name=tid.substring(0,index);const path=tid.substring(index+1);return{drives:get_drives(name),path:path}}function get_drives(name){const{settings,api,server}=__drives[name];if(settings.v3==null){settings.v3=false;const data=http.get(server+"/api/public/settings").json().data;if(Array.isArray(data)){settings.title=data.find(x=>x.key==="title")?.value;settings.v3=false;settings.version=data.find(x=>x.key==="version")?.value;settings.enableSearch=data.find(x=>x.key==="enable search")?.value==="true"}else{settings.title=data.title;settings.v3=true;settings.version=data.version;settings.enableSearch=false}api.path=settings.v3?"/api/fs/list":"/api/public/path";api.file=settings.v3?"/api/fs/get":"/api/public/path";api.search=settings.v3?"/api/public/search":"/api/public/search"}return __drives[name]}function init(ext){console.log("当前版本号:"+VERSION);let data;if(typeof ext=="object"){data=ext;print("alist ext:object")}else if(typeof ext=="string"){if(ext.startsWith("http")){let alist_data=ext.split(";");let alist_data_url=alist_data[0];limit_search_show=alist_data.length>1?Number(alist_data[1])||limit_search_show:limit_search_show;search_type=alist_data.length>2?alist_data[2]:search_type;print(alist_data_url);data=http.get(alist_data_url).json()}else{print("alist ext:json string");data=JSON.parse(ext)}}let drives=[];if(Array.isArray(data)&&data.length>0&&data[0].hasOwnProperty("server")&&data[0].hasOwnProperty("name")){drives=data}else if(!Array.isArray(data)&&data.hasOwnProperty("drives")&&Array.isArray(data.drives)){drives=data.drives.filter(it=>it.type&&it.type==="alist"||!it.type)}print(drives);searchDriver=(drives.find(x=>x.search)||{}).name||"";if(!searchDriver&&drives.length>0){searchDriver=drives[0].name}print(searchDriver);drives.forEach(item=>{let _path_param=[];if(item.params){_path_param=Object.keys(item.params);_path_param.sort((a,b)=>a.length-b.length)}if(item.password){let pwdObj={password:item.password};if(!item.params){item.params={"/":pwdObj}}else{item.params["/"]=pwdObj}_path_param.unshift("/")}__drives[item.name]={name:item.name,server:item.server.endsWith("/")?item.server.rstrip("/"):item.server,startPage:item.startPage||"/",showAll:item.showAll===true,search:!!item.search,params:item.params||{},_path_param:_path_param,settings:{},api:{},getParams(path){const key=this._path_param.find(x=>path.startsWith(x));return Object.assign({},this.params[key],{path:path})},getPath(path){const res=http.post(this.server+this.api.path,{data:this.getParams(path)}).json();return this.settings.v3?res.data.content:res.data.files},getFile(path){let raw_url=this.server+"/d"+path;raw_url=encodeURI(raw_url);let data={raw_url:raw_url,raw_url1:raw_url};if(playRaw===1){try{const res=http.post(this.server+this.api.file,{data:this.getParams(path)}).json();data=this.settings.v3?res.data:res.data.files[0];if(!this.settings.v3){data.raw_url=data.url}data.raw_url1=raw_url;return data}catch(e){return data}}else{return data}},isFolder(data){return data.type===1},isVideo(data){return this.settings.v3?data.type===2||data.type===0||data.type===3:data.type===3||data.type===0||data.type===4},is_subt(data){if(data.type===1){return false}const ext=/\.(srt|ass|scc|stl|ttml)$/;return ext.test(data.name)},getPic(data){let pic=this.settings.v3?data.thumb:data.thumbnail;return pic||(this.isFolder(data)?"http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png":"")},getTime(data,isStandard){isStandard=isStandard||false;try{let tTime=data.updated_at||data.time_str||data.modified||"";let date="";if(tTime){tTime=tTime.split("T");date=tTime[0];if(isStandard){date=date.replace(/-/g,"/")}tTime=tTime[1].split(/Z|\./);date+=" "+tTime[0]}return date}catch(e){return""}}}});print("init执行完毕")}function home(filter){let classes=Object.keys(__drives).map(key=>({type_id:`${key}$${__drives[key].startPage}`,type_name:key,type_flag:"1"}));let filter_dict={};let filters=[{key:"order",name:"排序",value:[{n:"名称⬆️",v:"vod_name_asc"},{n:"名称⬇️",v:"vod_name_desc"},{n:"中英⬆️",v:"vod_cn_asc"},{n:"中英⬇️",v:"vod_cn_desc"},{n:"时间⬆️",v:"vod_time_asc"},{n:"时间⬇️",v:"vod_time_desc"},{n:"大小⬆️",v:"vod_size_asc"},{n:"大小⬇️",v:"vod_size_desc"},{n:"无",v:"none"}]},{key:"show",name:"播放展示",value:[{n:"单集",v:"single"},{n:"全集",v:"all"}]}];classes.forEach(it=>{filter_dict[it.type_id]=filters});print("----home----");print(classes);return JSON.stringify({class:classes,filters:filter_dict})}function homeVod(params){let _post_data={pageNum:0,pageSize:100};let _post_url="https://pbaccess.video.qq.com/trpc.videosearch.hot_rank.HotRankServantHttp/HotRankHttp";let data=http.post(_post_url,{data:_post_data}).json();let _list=[];try{data=data["data"]["navItemList"][0]["hotRankResult"]["rankItemList"];data.forEach(it=>{_list.push({vod_name:it.title,vod_id:"msearch:"+it.title,vod_pic:"https://avatars.githubusercontent.com/u/97389433?s=120&v=4",vod_remarks:it.changeOrder})})}catch(e){print("Alist获取首页推荐发送错误:"+e.message)}return JSON.stringify({list:_list})}function category(tid,pg,filter,extend){let orid=tid.replace(/#all#|#search#/g,"");let{drives,path}=get_drives_path(orid);const id=orid.endsWith("/")?orid:orid+"/";const list=drives.getPath(path);let subList=[];let vodFiles=[];let allList=[];let fl=filter?extend:{};if(fl.show){showMode=fl.show}list.forEach(item=>{if(drives.is_subt(item)){subList.push(item.name)}if(!drives.showAll&&!drives.isFolder(item)&&!drives.isVideo(item)){return}let vod_time=drives.getTime(item);let vod_size=get_size(item.size);let remark=vod_time.split(" ")[0].substr(3)+"\t"+vod_size;let vod_id=id+item.name+(drives.isFolder(item)?"/":"");if(showMode==="all"){vod_id+="#all#"}print(vod_id);const vod={vod_id:vod_id,vod_name:item.name.replaceAll("$","").replaceAll("#",""),vod_pic:drives.getPic(item),vod_time:vod_time,vod_size:item.size,vod_tag:drives.isFolder(item)?"folder":"file",vod_remarks:drives.isFolder(item)?remark+" 文件夹":remark};if(drives.isVideo(item)){vodFiles.push(vod)}allList.push(vod)});if(vodFiles.length===1&&subList.length>0){let sub;if(subList.length===1){sub=subList[0]}else{let subs=JSON.parse(JSON.stringify(subList));subs.sort((a,b)=>{let a_similar=(a.includes("chs")?100:0)+levenshteinDistance(a,vodFiles[0].vod_name);let b_similar=(b.includes("chs")?100:0)+levenshteinDistance(b,vodFiles[0].vod_name);if(a_similar>b_similar){return 1}else{return-1}});sub=subs.slice(-1)[0]}vodFiles[0].vod_id+="@@@"+sub;vodFiles[0].vod_remarks+="🏷️"}else{vodFiles.forEach(item=>{const lh=0;let sub;subList.forEach(s=>{const l=levenshteinDistance(s,item.vod_name);if(l>60&&l>lh){sub=s}});if(sub){item.vod_id+="@@@"+sub;item.vod_remarks+="🏷️"}})}if(fl.order){let key=fl.order.split("_").slice(0,-1).join("_");let order=fl.order.split("_").slice(-1)[0];print(`排序key:${key},排序order:${order}`);if(key.includes("name")){detail_order="name";allList=sortListByName(allList,key,order)}else if(key.includes("cn")){detail_order="cn";allList=sortListByCN(allList,"vod_name",order)}else if(key.includes("time")){detail_order="time";allList=sortListByTime(allList,key,order)}else if(key.includes("size")){detail_order="size";allList=sortListBySize(allList,key,order)}else if(fl.order.includes("none")){detail_order="none";print("不排序")}}else{if(detail_order!=="none"){allList=sortListByName(allList,"vod_name","asc")}}print("----category----"+`tid:${tid},detail_order:${detail_order},showMode:${showMode}`);return JSON.stringify({page:1,pagecount:1,limit:allList.length,total:allList.length,list:allList})}function getAll(otid,tid,drives,path){try{const content=category(tid,null,false,null);const isFile=isMedia(otid.replace(/#all#|#search#/g,"").split("@@@")[0]);const{list}=JSON.parse(content);let vod_play_url=[];list.forEach(x=>{if(x.vod_tag==="file"){let vid=x.vod_id.replace(/#all#|#search#/g,"");vod_play_url.push(`${x.vod_name}$${vid.substring(vid.indexOf("$")+1)}`)}});const pl=path.split("/").filter(it=>it);let vod_name=pl[pl.length-1]||drives.name;if(vod_name===drives.name){print(pl)}if(otid.includes("#search#")){vod_name+="[搜]"}let vod={vod_id:otid,vod_name:vod_name,type_name:"文件夹",vod_pic:"https://avatars.githubusercontent.com/u/97389433?s=120&v=4",vod_content:tid,vod_tag:"folder",vod_play_from:drives.name,vod_play_url:vod_play_url.join("#"),vod_remarks:drives.settings.title};print("----detail1----");print(vod);return JSON.stringify({list:[vod]})}catch(e){print(e.message);let list=[{vod_name:"无数据,防无限请求",type_name:"文件夹",vod_id:"no_data",vod_remarks:"不要点,会崩的",vod_pic:"https://ghproxy.com/https://raw.githubusercontent.com/hjdhnx/dr_py/main/404.jpg",vod_actor:e.message,vod_director:tid,vod_content:otid}];return JSON.stringify({list:list})}}function detail(tid){let isSearch=tid.includes("#search#");let isAll=tid.includes("#all#");let otid=tid;tid=tid.replace(/#all#|#search#/g,"");let isFile=isMedia(tid.split("@@@")[0]);print(`isFile:${tid}?${isFile}`);let{drives,path}=get_drives_path(tid);print(`drives:${drives},path:${path},`);if(path.endsWith("/")){return getAll(otid,tid,drives,path)}else{if(isSearch&&!isFile){return getAll(otid,tid,drives,path)}else if(isAll){let new_tid;if(isFile){new_tid=tid.split("/").slice(0,-1).join("/")+"/"}else{new_tid=tid}print(`全集模式 tid:${tid}=>tid:${new_tid}`);let{drives,path}=get_drives_path(new_tid);return getAll(otid,new_tid,drives,path)}else if(isFile){let paths=path.split("@@@");let vod_name=paths[0].substring(paths[0].lastIndexOf("/")+1);let vod_title=vod_name;if(otid.includes("#search#")){vod_title+="[搜]"}let vod={vod_id:otid,vod_name:vod_title,type_name:"文件",vod_pic:"https://avatars.githubusercontent.com/u/97389433?s=120&v=4",vod_content:tid,vod_play_from:drives.name,vod_play_url:vod_name+"$"+path,vod_remarks:drives.settings.title};print("----detail2----");print(vod);return JSON.stringify({list:[vod]})}else{return JSON.stringify({list:[]})}}}function play(flag,id,flags){const drives=get_drives(flag);const urls=id.split("@@@");let vod={parse:0,playUrl:"",url:drives.getFile(urls[0]).raw_url};if(urls.length>=2){const path=urls[0].substring(0,urls[0].lastIndexOf("/")+1);vod.subt=drives.getFile(path+urls[1]).raw_url1}print("----play----");print(vod);return JSON.stringify(vod)}function search(wd,quick){print(__drives);print("可搜索的alist驱动:"+searchDriver);if(!searchDriver||!wd){return JSON.stringify({list:[]})}else{let driver=__drives[searchDriver];wd=wd.split(" ").filter(it=>it.trim()).join("+");print(driver);let surl=driver.server+"/search?box="+wd+"&url=";if(search_type){surl+="&type="+search_type}print("搜索链接:"+surl);let html=http.get(surl).text();let lists=[];try{lists=pdfa(html,"div&&ul&&a")}catch(e){}print(`搜索结果数:${lists.length},搜索结果显示数量限制:${limit_search_show}`);let vods=[];let excludeReg=/\.(pdf|epub|mobi|txt|doc|lrc)$/;let cnt=0;lists.forEach(it=>{let vhref=pdfh(it,"a&&href");if(vhref){vhref=unescape(vhref)}if(excludeReg.test(vhref)){return}if(cnt1024*1024*1024*1024){sz/=1024*1024*1024*1024;filesize="TB"}else if(sz>1024*1024*1024){sz/=1024*1024*1024;filesize="GB"}else if(sz>1024*1024){sz/=1024*1024;filesize="MB"}else if(sz>1024){sz/=1024;filesize="KB"}else{filesize="B"}let sizeStr=sz.toFixed(2)+filesize,index=sizeStr.indexOf("."),dou=sizeStr.substr(index+1,2);if(dou==="00"){return sizeStr.substring(0,index)+sizeStr.substr(index+3,2)}else{return sizeStr}}function levenshteinDistance(str1,str2){return 100-100*distance(str1,str2)/Math.max(str1.length,str2.length)}function naturalSort(options){if(!options){options={}}return function(a,b){if(options.key){a=a[options.key];b=b[options.key]}var EQUAL=0;var GREATER=options.order==="desc"?-1:1;var SMALLER=-GREATER;var re=/(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi;var sre=/(^[ ]*|[ ]*$)/g;var dre=/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;var hre=/^0x[0-9a-f]+$/i;var ore=/^0/;var normalize=function normalize(value){var string=""+value;return options.caseSensitive?string:string.toLowerCase()};var x=normalize(a).replace(sre,"")||"";var y=normalize(b).replace(sre,"")||"";var xN=x.replace(re,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");var yN=y.replace(re,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0");if(!x&&!y)return EQUAL;if(!x&&y)return GREATER;if(x&&!y)return SMALLER;var xD=parseInt(x.match(hre))||xN.length!=1&&x.match(dre)&&Date.parse(x);var yD=parseInt(y.match(hre))||xD&&y.match(dre)&&Date.parse(y)||null;var oFxNcL,oFyNcL;if(yD){if(xDyD)return GREATER}for(var cLoc=0,numS=Math.max(xN.length,yN.length);cLocoFyNcL)return GREATER}return EQUAL}}const sortListByName=(vodList,key,order)=>{if(!key){return vodList}order=order||"asc";return vodList.sort(naturalSort({key:key,order:order,caseSensitive:true}))};const getTimeInt=timeStr=>{return new Date(timeStr).getTime()};const sortListByTime=(vodList,key,order)=>{if(!key){return vodList}let ASCarr=vodList.sort((a,b)=>{a=a[key];b=b[key];return getTimeInt(a)-getTimeInt(b)});if(order==="desc"){ASCarr.reverse()}return ASCarr};const sortListBySize=(vodList,key,order)=>{if(!key){return vodList}let ASCarr=vodList.sort((a,b)=>{a=a[key];b=b[key];return(Number(a)||0)-(Number(b)||0)});if(order==="desc"){ASCarr.reverse()}return ASCarr};export default{init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search}; \ No newline at end of file diff --git a/lib/drpy-ym.js b/lib/drpy-ym.js deleted file mode 100644 index 184d6c9a..00000000 --- a/lib/drpy-ym.js +++ /dev/null @@ -1,1447 +0,0 @@ -import './util-ym.js'; -import cheerio from 'assets://js/lib/cheerio.min.js'; -import 'assets://js/lib/crypto-js.js' -// import muban from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js'; - -// const key = 'drpy_zbk'; -// eval(req('http://192.168.1.124:5705/libs/es6py.js').content); -function init_test() { - console.log("init_test_start"); - console.log(RKEY); - console.log(JSON.stringify(rule)); - // clearItem(RULE_CK); - // console.log(JSON.stringify(rule)); - // let aa = base64Encode('编码测试一下') - // log(aa); - // let bb = base64Decode(aa); - // log('bb:' + bb); - // console.log(request('https://www.baidu.com',{withHeaders:true})); - // console.log(request('https://www.baidu.com/favicon.ico', { toBase64: true })); - // require('http://192.168.10.99:5705/txt/pluto/drT.js'); - // console.log(typeof(drT)); - // console.log(drT.renderText('{{fl.cate}},hi, {{fl}}哈哈.{{fl}}',{sort: 1,cate:'movie'},'fl')); - console.log("init_test_end"); -} - -let rule = {}; -/** 已知问题记录 - * 1.影魔的jinjia2引擎不支持 {{fl}}对象直接渲染 - * Array.prototype.append = Array.prototype.push; 这种js执行后有毛病,for in 循环列表会把属性给打印出来 - * 2.import es6py.js但是里面的函数没有被装载进来.比如drpy规则报错setResult2 is undefiend - * 3.无法重复导入cheerio(怎么解决drpy和parseTag里都需要导入cheerio的问题) 无法在副文件导入cheerio (现在是全部放在drpy一个文件里了,凑合解决?) - * 4.有个错误不知道哪儿来的 executeScript: com.quickjs.JSObject$Undefined cannot be cast to java.lang.String 在 点击选集播放打印init_test_end后面打印 - * 5.需要实现 stringify 函数,比起JSON.stringify函数,它会原封不动保留中文不会编码unicode - * todo: jsp:{pdfa,pdfh,pd},json:{pdfa,pdfh,pd},jq:{pdfa,pdfh,pd} - * * 电脑看日志调试 - adb tcpip 5555 - adb connect 192.168.10.192 - adb devices -l - adb logcat -c - adb logcat | grep -i QuickJS - * **/ - - -/*** 以下是内置变量和解析方法 **/ -const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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'; // 源cookie的key值 -// const KEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); // 源的唯一标识 -const CATE_EXCLUDE = '首页|留言|APP|下载|资讯|新闻|动态'; -const TAB_EXCLUDE = '猜你|喜欢|APP|下载|剧情|热播'; -const OCR_RETRY = 3;//ocr验证重试次数 -// const OCR_API = 'http://dm.mudery.com:10000';//ocr在线识别接口 -// const OCR_API = 'http://192.168.3.239:5705/parse/ocr';//ocr在线识别接口 -const OCR_API = 'http://cms.nokia.press/parse/ocr';//ocr在线识别接口 -if (typeof (MY_URL) === 'undefined') { - var MY_URL; // 全局注入变量,pd函数需要 -} -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', 'data-original', 'data-src']; -const DOM_CHECK_ATTR = /(url|src|href|data-original|data-src)$/; -const SELECT_REGEX = /:eq|:lt|:gt|#/g; -const SELECT_REGEX_A = /:eq|:lt|:gt/g; - -function setResult(d) { - if (!Array.isArray(d)) { - return [] - } - VODS = []; - // print(d); - d.forEach(function (it) { - let obj = { - vod_id: it.url || '', - vod_name: it.title || '', - vod_remarks: it.desc || '', - vod_content: it.content || '', - vod_pic: it.pic_url || it.img || '', - }; - let keys = Object.keys(it); - if (keys.includes('tname')) { - obj.type_name = it.tname || ''; - } - if (keys.includes('tid')) { - obj.type_id = it.tid || ''; - } - if (keys.includes('year')) { - obj.vod_year = it.year || ''; - } - if (keys.includes('actor')) { - obj.vod_actor = it.actor || ''; - } - if (keys.includes('director')) { - obj.vod_director = it.director || ''; - } - if (keys.includes('area')) { - obj.vod_area = it.area || ''; - } - VODS.push(obj); - }); - return VODS -} -function setResult2(res) { - VODS = res.list || []; - return VODS -} -function setHomeResult(res) { - if (!res || typeof (res) !== 'object') { - return [] - } - return setResult(res.list); -} -// 猫了个咪 -function rc(js) { - if (js === 'maomi_aes.js') { - var a = CryptoJS.enc.Utf8.parse("625222f9149e961d"); - var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330"); - return { - De: function (word) { - word = CryptoJS.enc.Hex.parse(word) - return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - }, - En: function (word) { - // print(a); - // print(word); - var Encrypted = CryptoJS.AES.encrypt(word, a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return Encrypted.ciphertext.toString(); - } - }; - } - return {}; -} - -// 千万不要用for in 推荐 forEach (for in 会打乱顺序) -//猫函数 -function maoss(jxurl, ref, key) { - eval(getCryptoJS()); - try { - var getVideoInfo = function (text) { - return CryptoJS.AES.decrypt(text, key, { iv: iv, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); - }; - var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key; - if (ref) { - var html = request(jxurl, { - headers: { - 'Referer': ref - } - }); - } else { - var html = request(jxurl); - } - // print(html); - if (html.indexOf('&btwaf=') != -1) { - html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], { - headers: { - 'Referer': ref - } - }) - } - var token_iv = html.split('_token = "')[1].split('"')[0]; - var key = CryptoJS.enc.Utf8.parse(token_key); - var iv = CryptoJS.enc.Utf8.parse(token_iv); - // log("iv:"+iv); - // log(html); - // print(key); - // print(iv); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - // config.url = config.url.replace(/,/g,''); - // print(config.url); - if (!config.url.startsWith('http')) { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - config.url = CryptoJS.AES.decrypt(config.url, key, { - iv: iv, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - } - return config.url; - } catch (e) { - return ''; - } -} - -let VODS = [];// 一级或者搜索需要的数据列表 -let VOD = {};// 二级的单个数据 - -/** - * 重写pd方法-增加自动urljoin(没法重写,改个名继续骗) - * @param html - * @param parse - * @param uri - * @returns {*} - */ -function pD(html, parse, uri) { - let ret = pdfh(html, parse); - if (typeof (uri) === 'undefined' || !uri) { - uri = ''; - } - if (DOM_CHECK_ATTR.test(parse)) { - if (/http/.test(ret)) { - ret = ret.substr(ret.indexOf('http')); - } else { - ret = urljoin(MY_URL, ret) - } - } - // MY_URL = getItem('MY_URL',MY_URL); - // console.log(`规则${RKEY}打印MY_URL:${MY_URL},uri:${uri}`); - return ret -} - -const parseTags = { - jsp: { - pdfh: pdfh, - pdfa: pdfa, - pd: pD, - }, - 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: pdfh, - pdfa: pdfa, - pd(html, parse, uri) { - return parseTags.jq.pdfh(html, parse, MY_URL); - }, - }, - getParse(p0) {//非js开头的情况自动获取解析标签 - 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; - -/*** 后台需要实现的java方法并注入到js中 ***/ - -/** - * 读取本地文件->应用程序目录 - * @param filePath - * @returns {string} - */ -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 -} - -/** - * 处理返回的json数据 - * @param html - * @returns {*} - */ -function dealJson(html) { - try { - return html.match(/[\w|\W|\s|\S]*?(\{[\w|\W|\s|\S]*\})/).group[1]; - } catch (e) { - } - try { - html = JSON.parse(html); - } catch (e) { } - // console.log(typeof(html)); - return html; -} - -/** - * 验证码识别逻辑,需要java实现(js没有bytes类型,无法调用后端的传递图片二进制获取验证码文本的接口) - * @type {{api: string, classification: (function(*=): string)}} - */ -var OcrApi = { - api: OCR_API, - classification: function (img) { // img是byte类型,这里不方便搞啊 - let code = ''; - try { - let html = request(this.api, { data: { img: img }, headers: { 'User-Agent': PC_UA }, 'method': 'POST' }); - html = JSON.parse(html); - code = html.url || ''; - } catch (e) { } - return code - } -}; -/** - * 验证码识别,暂未实现 - * @param url 验证码图片链接 - * @returns {string} 验证成功后的cookie - */ -function verifyCode(url) { - let cnt = 0; - let host = getHome(url); - let cookie = ''; - while (cnt < OCR_RETRY) { - try { - // let obj = {headers:headers,timeout:timeout}; - let yzm_url = `${host}/index.php/verify/index.html`; - console.log(`验证码链接:${yzm_url}`); - let hhtml = request(yzm_url, { withHeaders: true, toBase64: true }); - let json = JSON.parse(hhtml); - if (!cookie) { - cookie = json['set-cookie'] ? json['set-cookie'].split(';')[0] : ''; - } - // console.log(hhtml); - console.log('cookie:' + cookie); - let img = json.body; - // console.log(img); - 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, 'User-Agent': MOBILE_UA }, 'method': 'POST' }); - // console.log(html); - html = JSON.parse(html); - if (html.msg === 'ok') { - console.log(`第${cnt + 1}次验证码提交成功`); - return cookie // 需要返回cookie - } else if (html.msg !== 'ok' && cnt + 1 >= OCR_RETRY) { - cookie = ''; // 需要清空返回cookie - } - } catch (e) { - console.log(`第${cnt + 1}次验证码提交失败:${e.message}`); - if (cnt + 1 >= OCR_RETRY) { - cookie = ''; - } - } - cnt += 1 - } - return cookie -} - -/** - * 存在数据库配置表里, key字段对应值value,没有就新增,有就更新,调用此方法会清除key对应的内存缓存 - * @param k 键 - * @param v 值 - */ -function setItem(k, v) { - local.set(RKEY, k, v); - console.log(`规则${RKEY}设置${k} => ${v}`) -} - -/** - * 获取数据库配置表对应的key字段的value,没有这个key就返回value默认传参.需要有缓存,第一次获取后会存在内存里 - * @param k 键 - * @param v 值 - * @returns {*} - */ -function getItem(k, v) { - return local.get(RKEY, k) || v; -} - -/** - * 删除数据库key对应的一条数据,并清除此key对应的内存缓存 - * @param k - */ -function clearItem(k) { - local.delete(RKEY, k); -} - -/*** js自封装的方法 ***/ - -/** - * 获取链接的host(带http协议的完整链接) - * @param url 任意一个正常完整的Url,自动提取根 - * @returns {string} - */ -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 -} - -/** - * get参数编译链接,类似python params字典自动拼接 - * @param url 访问链接 - * @param obj 参数字典 - * @returns {*} - */ -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 -} - -/** - * 远程依赖执行函数 - * @param url 远程js地址 - */ -function require(url) { - eval(request(url)); -} -/** - * 海阔网页请求函数完整封装 - * @param url 请求链接 - * @param obj 请求对象 {headers:{},method:'',timeout:5000,body:'',withHeaders:false} - * @returns {string|string|DocumentFragment|*} - */ -function request(url, obj) { - 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); - } - 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 (!keys.includes('referer')) { - headers['Referer'] = getHome(url); - } - obj.headers = headers; - } - console.log(JSON.stringify(obj.headers)); - if (typeof (obj.headers.body) != 'undefined' && obj.headers.body && typeof (obj.headers.body) === 'string') { - let data = {}; - obj.headers.body.split('&').forEach(it => { - data[it.split('=')[0]] = it.split('=')[1] - }); - obj.data = data; - delete obj.headers.body - } - if (!url) { - return obj.withHeaders ? '{}' : '' - } - if (obj.toBase64) { // 返回base64,用于请求图片 - obj.buffer = 2; - delete obj.toBase64 - } - console.log('request:' + url); - let res = req(url, obj); - let html = res.content || ''; - // console.log(html); - if (obj.withHeaders) { - let htmlWithHeaders = res.headers; - htmlWithHeaders.body = html; - return JSON.stringify(htmlWithHeaders); - } else { - return html - } -} - -fetch = request; -print = function (data) { - data = data || ''; - if (typeof (data) !== 'string') { - try { - data = JSON.stringify(data); - } catch (e) { - console.log('print:' + e.message) - } - } - console.log(data); -} -log = console.log; -/** - * 检查宝塔验证并自动跳过获取正确源码 - * @param html 之前获取的html - * @param url 之前的来源url - * @param obj 来源obj - * @returns {string|DocumentFragment|*} - */ -function checkHtml(html, url, obj) { - if (/\?btwaf=/.test(html)) { - let btwaf = html.match(/btwaf(.*?)"/)[1]; - url = url.split('#')[0] + '?btwaf' + btwaf; - html = request(url, obj); - } - return html -} - -/** - * 带一次宝塔验证的源码获取 - * @param url 请求链接 - * @param obj 请求参数 - * @returns {string|DocumentFragment} - */ -function getCode(url, obj) { - let html = request(url, obj); - html = checkHtml(html, url, obj); - return html -} - -/** - * 源rule专用的请求方法,自动注入cookie - * @param url 请求链接 - * @returns {string|DocumentFragment} - */ -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')) { - obj.headers['Cookie'] = cookie; - } else if (!obj.headers) { - obj.headers = { Cookie: cookie }; - } - } - let html = getCode(url, obj); - return html -} - -/** - * 首页分类解析,筛选暂未实现 - * @param homeObj 首页传参对象 - * @returns {string} - */ -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; i < cnt; i++) { - classes.push({ - 'type_id': urls[i], - 'type_name': names[i] - }); - } - } - - if (homeObj.class_parse) { - let p = homeObj.class_parse.split(';'); - if (p.length >= 4) { - try { - let html = getHtml(homeObj.MY_URL); - if (html) { - homeHtmlCache = html; - let list = pdfa(html, p[0]); - 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 = pdfh(it, p[2]); - if (p[3]) { - 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); - -} - -/** - * 首页推荐列表解析 - * @param homeVodObj - * @returns {string} - */ -function homeVodParse(homeVodObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - MY_URL = homeVodObj.homeUrl; - // setItem('MY_URL',MY_URL); - console.log(MY_URL); - let p = homeVodObj.推荐; - if (!p || typeof (p) !== 'string') { - return '{}' - } - p = p.trim(); - if (p.startsWith('js:')) { - const TYPE = 'home'; - var input = MY_URL; - const 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 _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:)/, ''); - // print(p[0]); - 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, p[0]); - // console.log(items.length); - for (let item of items) { - // console.log(p[1]); - let items2 = _pdfa(item, p[1]); - // console.log(items2.length); - for (let item2 of items2) { - try { - let title = _pdfh(item2, p[2]); - let img = ''; - try { - img = _pd(item2, p[3]) - } catch (e) { - } - let desc = _pdfh(item2, p[4]); - let links = []; - for (let p5 of p[5].split('+')) { - let link = !homeVodObj.detailUrl ? _pd(item2, p5, MY_URL) : _pdfh(item2, p5); - links.push(link); - } - let vod = { - vod_name: title, - vod_pic: img, - vod_remarks: desc, - vod_id: links.join('$') - }; - // print(vod); - d.push(vod); - } catch (e) { - console.log('首页列表处理发生错误:' + e.message); - } - - } - } - } else { - let items = _pdfa(html, p[0]); - for (let item of items) { - try { - let title = _pdfh(item, p[1]); - let img = ''; - try { - img = _pd(item, p[2], MY_URL); - } catch (e) { - - } - let desc = _pdfh(item, p[3]); - let links = []; - for (let p5 of p[4].split('+')) { - let link = !homeVodObj.detailUrl ? _pd(item, p5, MY_URL) : _pdfh(item, p5); - links.push(link); - } - let vod = { - vod_name: title, - vod_pic: img, - vod_remarks: desc, - vod_id: links.join('$') - }; - d.push(vod); - - } catch (e) { - - } - - } - - } - - } catch (e) { - - } - } - // console.log(JSON.stringify(d)); - return JSON.stringify({ - list: d - }) -} - -/** - * 一级分类页数据解析 - * @param cateObj - * @returns {string} - */ -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).replaceAll('fypage', cateObj.pg); - let url = cateObj.url.replaceAll('fyclass', cateObj.tid); - 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); - } - // console.log('filter:'+cateObj.filter); - let fl = cateObj.filter ? cateObj.extend : {}; - let new_url; - new_url = cheerio.jinja2(url, { fl: fl }); - // if (/object Object/.test(new_url)) { - // new_url = drT.renderText(url, fl); - // } - url = new_url; - } - if (/fypage/.test(url)) { - if (url.includes('(') && url.includes(')')) { - let url_rep = url.match(/.*?\((.*)\)/)[1]; - // console.log(url_rep); - let cnt_page = url_rep.replaceAll('fypage', cateObj.pg); - // console.log(cnt_page); - let cnt_pg = eval(cnt_page); - // console.log(cnt_pg); - url = url.replaceAll(url_rep, cnt_pg).replaceAll('(', '').replaceAll(')', ''); - } else { - url = url.replaceAll('fypage', cateObj.pg); - } - } - if (cateObj.pg === 1 && url.includes('[') && url.includes(']')) { - url = url.split('[')[1].split(']')[0]; - } - MY_URL = url; - // setItem('MY_URL',MY_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; - d.push({ - 'vod_id': vod_id, - 'vod_name': _pdfh(it, p[1]).replace(/\n|\t/g, '').trim(), - 'vod_pic': _pd(it, p[2], MY_URL), - 'vod_remarks': _pdfh(it, p[3]).replace(/\n|\t/g, '').trim(), - }); - }); - } - } catch (e) { - console.log(e.message); - } - } - // print(d); - return d.length < 1 ? '{}' : JSON.stringify({ - 'page': parseInt(cateObj.pg), - 'pagecount': 999, - 'limit': 20, - 'total': 999, - 'list': d, - }); -} - -/** - * 搜索列表数据解析 - * @param searchObj - * @returns {string} - */ -function searchParse(searchObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - if (!searchObj.searchUrl) { - return '{}' - } - let p = searchObj.搜索 === '*' && rule.一级 ? rule.一级 : searchObj.搜索; - if (!p || typeof (p) !== 'string') { - return '{}' - } - p = p.trim(); - let url = searchObj.searchUrl.replaceAll('**', searchObj.wd).replaceAll('fypage', searchObj.pg); - MY_URL = url; - console.log(MY_URL); - // setItem('MY_URL',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 _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 (/系统安全验证|输入验证码/.test(html)) { - let cookie = verifyCode(MY_URL); - if (cookie) { - console.log(`本次成功过验证,cookie:${cookie}`); - setItem(RULE_CK, cookie); - } else { - console.log(`本次自动过搜索验证失败,cookie:${cookie}`); - } - // obj.headers['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, 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 ob = { - 'vod_id': link, - 'vod_name': _pdfh(it, p[1]).replace(/\n|\t/g, '').trim(), - 'vod_pic': _pd(it, p[2], MY_URL), - 'vod_remarks': _pdfh(it, p[3]).replace(/\n|\t/g, '').trim(), - }; - if (p.length > 5 && p[5]) { - ob.vod_content = _pdfh(it, p[5]); - } - d.push(ob); - }); - - } - } catch (e) { - return '{}' - } - - } - return JSON.stringify({ - 'page': parseInt(searchObj.pg), - 'pagecount': 10, - 'limit': 20, - 'total': 100, - 'list': d, - }); -} - -/** - * 二级详情页数据解析 - * @param detailObj - * @returns {string} - */ -function detailParse(detailObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let vod = { - vod_id: detailObj.orId, //"id", - vod_name: "片名", - 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; - console.log(MY_URL); - // setItem('MY_URL',MY_URL); - if (p === '*') { - vod.vod_play_from = '道长在线'; - vod.vod_remarks = detailUrl; - vod.vod_actor = '没有二级,只有一级链接直接嗅探播放'; - vod.vod_content = MY_URL; - vod.vod_play_url = '嗅探播放$' + MY_URL; - } else if (typeof (p) === 'string' && p.trim().startsWith('js:')) { - const TYPE = 'detail'; - var input = MY_URL; - eval(p.trim().replace('js:', '')); - vod = VOD; - console.log(JSON.stringify(vod)); - } else if (p && typeof (p) === 'object') { - if (!html) { - html = getHtml(MY_URL); - } - let _impJQP = true; - let _ps; - if (p.is_json) { - _ps = parseTags.json; - html = dealJson(html); - _impJQP = false; - } else if (p.is_jsp) { - _ps = parseTags.jsp; - } else if (p.is_jq) { - _ps = parseTags.jq; - } else { - _ps = parseTags.jq; - } - if (_impJQP) { - let c$ = cheerio.load(html); - html = { rr: c$, ele: c$('html')[0] } - } - _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]).replaceAll('\n', ' ').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:')) { - html = eval(p.重定向.replace('js:', '')); - if (_impJQP) { - let c$ = cheerio.load(html); - html = { rr: c$, ele: c$('html')[0] } - } - } - - // console.log(2); - if (p.tabs) { - let p_tab = p.tabs.split(';')[0]; - console.log(p_tab); - let vHeader = _pdfa(html, p_tab); - - console.log(vHeader.length); - for (let v of vHeader) { - let v_title = _pdfh(v, 'body&&Text'); - console.log(v_title); - if (tab_exclude && (new RegExp(tab_exclude)).test(v_title)) { - continue; - } - playFrom.push(v_title); - } - console.log(JSON.stringify(playFrom)); - } else { - playFrom = ['道长在线'] - } - vod.vod_play_from = playFrom.join(vod_play_from); - - // console.log(3); - let vod_play_url = '$$$'; - let vod_tab_list = []; - if (p.lists) { - for (let i = 0; i < playFrom.length; i++) { - let tab_name = playFrom[i]; - let tab_ext = p.tabs.split(';').length > 1 ? 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); - console.log(p1); - // console.log(html); - let vodList = []; - try { - vodList = _pdfa(html, p1); - console.log('len(vodList):' + vodList.length); - } catch (e) { - // console.log(e.message); - } - let new_vod_list = []; - let tabName = tab_ext ? _pdfh(html, tab_ext) : tab_name; - console.log(tabName); - // console.log('cheerio解析Text'); - vodList.forEach(it => { - // 请注意,这里要固定pdfh解析body&&Text,不需要下划线,没写错 - // new_vod_list.push(pdfh(it,'body&&Text')+'$'+_pd(it,'a&&href',MY_URL)); - // new_vod_list.push(cheerio.load(it).text() + '$' + _pd(it, 'a&&href', MY_URL)); - new_vod_list.push(_pdfh(it, 'body&&Text') + '$' + _pd(it, 'a&&href', MY_URL)); - }); - let vlist = new_vod_list.join('#'); - vod_tab_list.push(vlist); - } - } - vod.vod_play_url = vod_tab_list.join(vod_play_url); - } - // print(vod); - return JSON.stringify({ - list: [vod] - }) -} - -/** - * 选集播放点击事件解析 - * @param playObj - * @returns {string} - */ -function playParse(playObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - MY_URL = playObj.url; - if (!/http/.test(MY_URL)) { - try { - MY_URL = base64Decode(MY_URL); - } catch (e) { } - } - MY_URL = decodeURIComponent(MY_URL); - var input = MY_URL;//注入给免嗅js - let common_play = { - parse: 1, - url: 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.replace('js:', '').trim(); - print('开始执行js免嗅=>' + lazy_code); - eval(lazy_code); - lazy_play = typeof (input) === 'object' ? input : { - parse: 1, - jx: 1, - url: input - }; - } catch (e) { - print('js免嗅错误:' + e.message); - lazy_play = common_play; - } - } else { - lazy_play = common_play; - } - console.log(JSON.stringify(lazy_play)); - return JSON.stringify(lazy_play); -} - -/** - * js源预处理特定返回对象中的函数 - * @param ext - */ -function init(ext) { - console.log('init'); - try { - // make shared jsContext happy - if (typeof (globalThis.mubanJs) === 'undefined') { - let mubanJs = request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js', { 'User-Agent': MOBILE_UA }); - mubanJs = mubanJs.replace('export default', '(function() {return muban;}()) // export default'); - globalThis.mubanJs = mubanJs; - } - let muban = eval(globalThis.mubanJs); - if (typeof ext == 'object') { - rule = ext; - if (rule.template) { - rule = Object.assign(muban[rule.template], rule); - } - } else if (typeof ext == 'string') { - if (ext.startsWith('http')) { - let js = request(ext, { 'method': 'GET' }); - if (js) { - eval(js.replace('var rule', 'rule')); - } - } - } else { - eval(ext.replace('var rule', '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.host = (rule.host || '').rstrip('/'); - 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.detailUrl = rule.host && rule.detailUrl ? urljoin(rule.host, rule.detailUrl) : rule.detailUrl; - 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; - } - rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host, rule.searchUrl) : rule.searchUrl; - - rule.timeout = rule.timeout || 5000; - rule.encoding = rule.编码 || rule.encoding || 'utf-8'; - 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); - } - } - } - } catch (e) { - console.log('处理headers发生错误:' + e.message); - } - } - // print(rule.headers); - rule_fetch_params = { 'headers': rule.headers || false, 'timeout': rule.timeout, 'encoding': rule.encoding }; - oheaders = rule.headers || {}; - RKEY = typeof (key) !== 'undefined' && key ? key : 'drpy_' + (rule.title || rule.host); - init_test(); - } catch (e) { - console.log('init_test发生错误:' + e.message); - } -} - -let homeHtmlCache = undefined; - -/** - * js源获取首页分类和筛选特定返回对象中的函数 - * @param filter 筛选条件字典对象 - * @returns {string} - */ -function home(filter) { - console.log("home"); - let homeObj = { - filter: rule.filter || false, - MY_URL: rule.homeUrl, - class_name: rule.class_name || '', - class_url: rule.class_url || '', - class_parse: rule.class_parse || '', - cate_exclude: rule.cate_exclude, - }; - return homeParse(homeObj); -} - -/** - * js源获取首页推荐数据列表特定返回对象中的函数 - * @param params - * @returns {string} - */ -function homeVod(params) { - let homeVodObj = { - 推荐: rule.推荐, - double: rule.double, - homeUrl: rule.homeUrl, - detailUrl: rule.detailUrl - }; - return homeVodParse(homeVodObj) - // return "{}"; -} - -/** - * js源获取分类页一级数据列表特定返回对象中的函数 - * @param tid 分类id - * @param pg 页数 - * @param filter 当前选中的筛选条件 - * @param extend 扩展 - * @returns {string} - */ -function category(tid, pg, filter, extend) { - let cateObj = { - url: rule.url, - 一级: rule.一级, - tid: tid, - pg: parseInt(pg), - filter: filter, - extend: extend - }; - // console.log(JSON.stringify(extend)); - return categoryParse(cateObj) -} - -/** - * js源获取二级详情页数据特定返回对象中的函数 - * @param vod_url 一级列表中的vod_id或者是带分类的自拼接 vod_id 如 fyclass$vod_id - * @returns {string} - */ -function detail(vod_url) { - let orId = vod_url; - let fyclass = ''; - if (vod_url.indexOf('$') > -1) { - let tmp = vod_url.split('$'); - fyclass = tmp[0]; - vod_url = tmp[1]; - } - let detailUrl = vod_url; - 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.二级, - detailUrl: detailUrl, - fyclass: fyclass, - tab_exclude: rule.tab_exclude, - } - return detailParse(detailObj) -} - -/** - * js源选集按钮播放点击事件特定返回对象中的函数 - * @param flag 线路名 - * @param id 播放按钮的链接 - * @param flags 全局配置的flags是否需要解析的标识列表 - * @returns {string} - */ -function play(flag, id, flags) { - let playObj = { - url: id, - flag: flag, - flags: flags - } - return playParse(playObj); -} - -/** - * js源搜索返回的数据列表特定返回对象中的函数 - * @param wd 搜索关键字 - * @param quick 是否来自快速搜索 - * @returns {string} - */ -function search(wd, quick) { - let searchObj = { - searchUrl: rule.searchUrl, - 搜索: rule.搜索, - wd: wd, - //pg: pg, - pg: 1, - quick: quick, - }; - // console.log(JSON.stringify(searchObj)); - return searchParse(searchObj) -} - -function DRPY() {//导出函数 - return { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - } -} - - -let pd = pD; - -// 导出函数对象 -__JS_SPIDER__ = { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - DRPY: DRPY -} diff --git a/lib/drpy.js b/lib/drpy.js deleted file mode 100644 index 0e5545c8..00000000 --- a/lib/drpy.js +++ /dev/null @@ -1,2366 +0,0 @@ -// import 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/es6py.js'; -// import {是否正版,urlDeal,setResult,setResult2,setHomeResult,maoss,urlencode} from 'http://192.168.10.103:5705/libs/es6py.js'; -// import 'http://192.168.1.124:5705/libs/es6py.js'; -import cheerio from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/cheerio.min.js'; -// import cheerio from 'http://192.168.10.103:5705/libs/cheerio.min.js'; -import 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-js.js'; -import 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/drT.js'; -import 模板 from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js'; -import {gbkTool} from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/gbk.js' -// import 'http://192.168.10.103:5705/libs/drT.js'; -// import muban from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js'; -// import muban from 'http://192.168.10.103:5705/admin/view/模板.js'; - -// const key = 'drpy_zbk'; -// eval(req('http://192.168.1.124:5705/libs/es6py.js').content); -function init_test(){ - // console.log(typeof(CryptoJS)); - console.log("init_test_start"); - console.log("当前版本号:"+VERSION); - console.log(RKEY); - console.log(JSON.stringify(rule)); - // console.log('123456的md5值是:'+md5('123456')); - // let aa = base64Encode('编码测试一下') - // log(aa); - // let bb = base64Decode(aa); - // log('bb:'+bb); - // clearItem(RULE_CK); - // console.log(JSON.stringify(rule)); - // console.log(request('https://www.baidu.com',{withHeaders:true})); - // console.log(request('https://www.baidu.com/favicon.ico',{toBase64:true})); - // require('http://192.168.10.99:5705/txt/pluto/drT.js'); - // console.log(typeof(drT)); - // console.log(drT.renderText('{{fl.cate}},hi, {{fl}}哈哈.{{fl}}',{sort: 1,cate:'movie'},'fl')); - console.log("init_test_end"); -} - -/** - * 执行预处理代码 - */ -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 { - // code里可以进行get 或者 post请求cookie并改变rule.headers 里的cookie - // 直接操作 rule_fetch_params 这个变量 .headers.Cookie - eval(code); - }catch (e) { - console.log('预处理执行失败:'+e.message); - } - } -} - -let rule = {}; -const VERSION = 'drpy1 3.9.43beta1 20230607'; -/** 已知问题记录 - * 1.影魔的jinjia2引擎不支持 {{fl}}对象直接渲染 (有能力解决的话尽量解决下,支持对象直接渲染字符串转义,如果加了|safe就不转义)[影魔牛逼,最新的文件发现这问题已经解决了] - * Array.prototype.append = Array.prototype.push; 这种js执行后有毛病,for in 循环列表会把属性给打印出来 (这个大毛病需要重点排除一下) - * 2.import es6py.js但是里面的函数没有被装载进来.比如drpy规则报错setResult2 is undefiend(合并文件了可以不管了) - * 3.无法重复导入cheerio(怎么解决drpy和parseTag里都需要导入cheerio的问题) 无法在副文件导入cheerio (现在是全部放在drpy一个文件里了,凑合解决?) - * 4.有个错误不知道哪儿来的 executeScript: com.quickjs.JSObject$Undefined cannot be cast to java.lang.String 在 点击选集播放打印init_test_end后面打印(貌似不影响使用) - * 5.需要实现 stringify 函数,比起JSON.stringify函数,它会原封不动保留中文不会编码unicode - * 6.base64Encode,base64Decode,md5函数还没有实现 (抄影魔代码实现了) - * 7.eval(getCryptoJS());还没有实现 (可以空实现了,以后遇到能忽略) - * done: jsp:{pdfa,pdfh,pd},json:{pdfa,pdfh,pd},jq:{pdfa,pdfh,pd} - * * 电脑看日志调试 - adb tcpip 5555 - adb connect 192.168.10.192 - adb devices -l - adb logcat -c - adb logcat | grep -i QuickJS - adb logcat -c -b events - adb logcat -c -b main -b events -b radio -b system - adb logcat > 2.log DRPY:E | grep -i QuickJS - * **/ - - -/*** 以下是内置变量和解析方法 **/ -const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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'; // 源cookie的key值 -// const KEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); // 源的唯一标识 -const CATE_EXCLUDE = '首页|留言|APP|下载|资讯|新闻|动态'; -const TAB_EXCLUDE = '猜你|喜欢|下载|剧情|热播'; -const OCR_RETRY = 3;//ocr验证重试次数 -// const OCR_API = 'http://dm.mudery.com:10000';//ocr在线识别接口 -// const OCR_API = 'http://192.168.3.239:5705/parse/ocr';//ocr在线识别接口 -// const OCR_API = 'http://cms.nokia.press/parse/ocr';//ocr在线识别接口 -// const OCR_API = 'http://cms.nokia.press:5707/parse/ocr';//ocr在线识别接口 -const OCR_API = 'http://drpy.nokia.press:8028/ocr/drpy/text';//ocr在线识别接口 -if(typeof(MY_URL)==='undefined'){ - var MY_URL; // 全局注入变量,pd函数需要 -} -var HOST; -var RKEY; // 源的唯一标识 -var fetch; -var print; -var log; -var rule_fetch_params; -var fetch_params; // 每个位置单独的 -var oheaders; -// var play_url; // 二级详情页注入变量,为了适配js模式0 (不在这里定义了,直接二级里定义了个空字符串) -var _pdfh; -var _pdfa; -var _pd; -// const DOM_CHECK_ATTR = ['url', 'src', 'href', 'data-original', 'data-src']; -const DOM_CHECK_ATTR = /(url|src|href|-original|-src|-play|-url)$/; -const SELECT_REGEX = /:eq|:lt|:gt|#/g; -const SELECT_REGEX_A = /:eq|:lt|:gt/g; - -/** -es6py扩展 - */ -if (typeof Object.assign != 'function') { - Object.assign = function () { - var target = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; -} -if (!String.prototype.includes) { - String.prototype.includes = function (search, start) { - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > this.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) {//this是空或者未定义,抛出错误 - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this);//将this转变成对象 - var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0 - - if (len === 0) {//length为0直接返回false未找到目标值 - return false; - } - - var n = fromIndex | 0;//查找起始索引 - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);//计算正确起始索引,因为有可能是负值 - - while (k < len) {//从起始索引处开始循环 - if (o[k] === searchElement) {//如果某一位置与寻找目标相等,返回true,找到了 - return true; - } - k++; - } - return false;//未找到,返回false - } - }); -} -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (prefix){ - return this.slice(0, prefix.length) === prefix; - }; -} -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function(suffix) { - return this.indexOf(suffix, this.length - suffix.length) !== -1; - }; -} -Object.prototype.myValues=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; -} -if (typeof Object.prototype.values != 'function') { - Object.prototype.values=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; - } -} -if (typeof Array.prototype.join != 'function') { - Array.prototype.join = function (emoji) { - // emoji = emoji||','; - emoji = emoji||''; - let self = this; - let str = ""; - let i = 0; - if (!Array.isArray(self)) {throw String(self)+'is not Array'} - if(self.length===0){return ''} - if (self.length === 1){return String(self[0])} - i = 1; - str = this[0]; - for (; i < self.length; i++) { - str += String(emoji)+String(self[i]); - } - return str; - }; -} - -String.prototype.rstrip = function (chars) { - let regex = new RegExp(chars + "$"); - return this.replace(regex, ""); -}; - -Array.prototype.append = Array.prototype.push; -String.prototype.strip = String.prototype.trim; -function 是否正版(vipUrl){ - let flag = new RegExp('qq\.com|iqiyi\.com|youku\.com|mgtv\.com|bilibili\.com|sohu\.com|ixigua\.com|pptv\.com|miguvideo\.com|le\.com|1905\.com|fun\.tv'); - return flag.test(vipUrl); -} -function urlDeal(vipUrl){ - if(!vipUrl){ - return '' - } - if(!是否正版(vipUrl)){ - return vipUrl - } - if(!/miguvideo/.test(vipUrl)){ - vipUrl=vipUrl.split('#')[0].split('?')[0]; - } - return vipUrl -} -function setResult(d){ - if(!Array.isArray(d)){ - return [] - } - VODS = []; - // print(d); - d.forEach(function (it){ - let obj = { - vod_id:it.url||'', - vod_name: it.title||'', - vod_remarks: it.desc||'', - vod_content: it.content||'', - vod_pic: it.pic_url||it.img||'', - }; - let keys = Object.keys(it); - if(keys.includes('tname')){ - obj.type_name = it.tname||''; - } - if(keys.includes('tid')){ - obj.type_id = it.tid||''; - } - if(keys.includes('year')){ - obj.vod_year = it.year||''; - } - if(keys.includes('actor')){ - obj.vod_actor = it.actor||''; - } - if(keys.includes('director')){ - obj.vod_director = it.director||''; - } - if(keys.includes('area')){ - obj.vod_area = it.area||''; - } - VODS.push(obj); - }); - return VODS -} -function setResult2(res){ - VODS = res.list||[]; - return VODS -} -function setHomeResult(res){ - if(!res||typeof(res)!=='object'){ - return [] - } - return setResult(res.list); -} -// 猫了个咪 -function rc(js) { - if (js === 'maomi_aes.js') { - var a = CryptoJS.enc.Utf8.parse("625222f9149e961d"); - var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330"); - return { - De: function (word) { - word = CryptoJS.enc.Hex.parse(word) - return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - }, - En: function (word) { - // print(a); - // print(word); - var Encrypted = CryptoJS.AES.encrypt(word, a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return Encrypted.ciphertext.toString(); - } - }; - } - return {}; -} - -// 千万不要用for in 推荐 forEach (for in 会打乱顺序) -//猫函数 -function maoss(jxurl, ref, key) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - eval(getCryptoJS()); - try { - var getVideoInfo = function (text) { - return CryptoJS.AES.decrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); - }; - var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key; - if (ref) { - var html = request(jxurl, { - headers: { - 'Referer': ref - } - }); - } else { - var html = request(jxurl); - } - // print(html); - if (html.indexOf('&btwaf=') != -1) { - html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], { - headers: { - 'Referer': ref - } - }) - } - var token_iv = html.split('_token = "')[1].split('"')[0]; - var key = CryptoJS.enc.Utf8.parse(token_key); - var iv = CryptoJS.enc.Utf8.parse(token_iv); - // log("iv:"+iv); - // log(html); - // print(key); - // print(iv); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - // config.url = config.url.replace(/,/g,''); - // print(config.url); - if (!config.url.startsWith('http')) { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - config.url = CryptoJS.AES.decrypt(config.url, key, { - iv: iv, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - } - return config.url; - } catch (e) { - return ''; - } -} - -function urlencode (str) { - str = (str + '').toString(); - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28'). - replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); -} - -function base64Encode(text){ - return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)); - // return text -} - -function base64Decode(text){ - return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text)); - // return text -} - -function md5(text) { - return CryptoJS.MD5(text).toString(); -} - -/** - * 字符串按指定编码 - * @param input - * @param encoding - * @returns {*} - */ -function encodeStr(input,encoding){ - encoding = encoding||'gbk'; - if(encoding.startsWith('gb')){ - const strTool = gbkTool(); - input = strTool.encode(input); - } - return input -} - -/** - * 字符串指定解码 - * @param input - * @param encoding - * @returns {*} - */ -function decodeStr(input,encoding){ - encoding = encoding||'gbk'; - if(encoding.startsWith('gb')){ - const strTool = gbkTool(); - input = strTool.decode(input); - } - return input -} - -function getCryptoJS(){ - // return request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-hiker.js'); - return 'console.log("CryptoJS已装载");' -} - -/** - * 强制正序算法 - * @param lists 待正序列表 - * @param key 正序键 - * @param option 单个元素处理函数 - * @returns {*} - */ -function forceOrder(lists,key,option){ - let start = Math.floor(lists.length/2); - let end = Math.min(lists.length-1,start+1); - if(start >= 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+=''; - // console.log(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 = [];// 二级的自定义线路列表 如: TABS=['道长在线','道长在线2'] -let LISTS = [];// 二级的自定义选集播放列表 如: LISTS=[['第1集$http://1.mp4','第2集$http://2.mp4'],['第3集$http://1.mp4','第4集$http://2.mp4']] -globalThis.encodeUrl = urlencode; -globalThis.urlencode = urlencode; - - - -/** - * url拼接 - * @param fromPath 初始当前页面url - * @param nowPath 相对当前页面url - * @returns {*} - */ -function urljoin(fromPath, nowPath) { - fromPath = fromPath||''; - nowPath = nowPath||''; - return joinUrl(fromPath, nowPath); - // try { - // // import Uri from './uri.min.js'; - // // var Uri = require('./uri.min.js'); - // // eval(request('https://cdn.bootcdn.net/ajax/libs/URI.js/1.19.11/URI.min.js')); - // // let new_uri = URI(nowPath, fromPath); - - // let new_uri = Uri(nowPath, fromPath); - // new_uri = new_uri.toString(); - // // console.log(new_uri); - // // return fromPath + nowPath - // return new_uri - // } - // catch (e) { - // console.log('urljoin发生错误:'+e.message); - // if(nowPath.startsWith('http')){ - // return nowPath - // }if(nowPath.startsWith('/')){ - // return getHome(fromPath)+nowPath - // } - // return fromPath+nowPath - // } -} -var urljoin2 = urljoin; - -// 内置 pdfh,pdfa,pd -const defaultParser = { - pdfh:pdfh, - pdfa:pdfa, - pd(html,parse,uri){ - let ret = this.pdfh(html,parse); - if(typeof(uri)==='undefined'||!uri){ - uri = ''; - } - if(DOM_CHECK_ATTR.test(parse)){ - if(/http/.test(ret)){ - ret = ret.substr(ret.indexOf('http')); - }else{ - ret = urljoin(MY_URL,ret) - } - } - return ret - }, -}; - - -/** - * pdfh原版优化,能取style属性里的图片链接 - * @param html 源码 - * @param parse 解析表达式 - * @returns {string|*} - */ -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]; - }catch (e) {} - } - return result -} - -/** - * pdfa原版优化,可以转换jq的html对象 - * @param html - * @param parse - * @returns {*} - */ -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); -} - -/** - * pd原版方法重写-增加自动urljoin - * @param html - * @param parse - * @param uri - * @returns {*} - */ -function pd2(html,parse,uri){ - let ret = pdfh2(html,parse); - if(typeof(uri)==='undefined'||!uri){ - uri = ''; - } - if(DOM_CHECK_ATTR.test(parse)){ - if(/http/.test(ret)){ - ret = ret.substr(ret.indexOf('http')); - }else{ - ret = urljoin(MY_URL,ret) - } - } - // MY_URL = getItem('MY_URL',MY_URL); - // console.log(`规则${RKEY}打印MY_URL:${MY_URL},uri:${uri}`); - return ret -} - -const parseTags = { - jsp:{ - pdfh:pdfh2, - pdfa:pdfa2, - pd:pd2, - }, - json:{ - pdfh(html, parse) { - if (!parse || !parse.trim()){ - return ''; - } - if (typeof(html) === 'string'){ - // print('jsonpath:pdfh字符串转dict'); - 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'){ - // print('jsonpath:pdfa字符串转dict'); - 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, base_url) { - if (!parse || !parse.trim()) { - return '' - } - let eleFind = typeof html === 'object'; - let option = undefined; - if (eleFind && parse.startsWith('body&&')) { - parse = parse.substr(6); - if (parse.indexOf('&&') < 0) { - option = parse.trim(); - parse = '*=*'; - } - } - if (parse.indexOf('&&') > -1) { - let sp = parse.split('&&'); - option = sp[sp.length - 1]; - sp.splice(sp.length - 1); - if (sp.length > 1) { - for (let i in sp) { - //Javascript自定义Array.prototype干扰for-in循环 - if(sp.hasOwnProperty(i)){ - if (!SELECT_REGEX.test(sp[i])) { - sp[i] = sp[i] + ':eq(0)'; - } - } - } - } else { - if (!SELECT_REGEX.test(sp[0])) { - sp[0] = sp[0] + ':eq(0)'; - } - } - parse = sp.join(' '); - } - let result = ''; - const $ = eleFind ? html.rr : cheerio.load(html); - let ret = eleFind ? ((parse === '*=*' || $(html.ele).is(parse)) ? html.ele : $(html.ele).find(parse)) : $(parse); - if (option) { - if (option === 'Text') { - result = $(ret).text(); - } - else if (option === 'Html') { - result = $(ret).html(); - } - else { - result = $(ret).attr(option); - if(/style/.test(option.toLowerCase())&&/url\(/.test(result)){ - try { - result = result.match(/url\((.*?)\)/)[1]; - }catch (e) {} - } - } - if (result && base_url && DOM_CHECK_ATTR.test(option)) { - if (/http/.test(result)) { - result = result.substr(result.indexOf('http')); - } else { - result = urljoin(base_url, result) - } - } - } else { - result = $(ret).toString(); - } - return result; - }, - pdfa(html, parse) { - if (!parse || !parse.trim()) { - print('!parse'); - return []; - } - let eleFind = typeof html === 'object'; - // print('parse前:'+parse); - if (parse.indexOf('&&') > -1) { - let sp = parse.split('&&'); - for (let i in sp) { - if(sp.hasOwnProperty(i)){ - if (!SELECT_REGEX_A.test(sp[i]) && i < sp.length - 1) { - if(sp[i]!=='body'){ - // sp[i] = sp[i] + ':eq(0)'; - sp[i] = sp[i] + ':first'; - } - } - } - } - parse = sp.join(' '); - } - // print('parse后:'+parse); - const $ = eleFind ? html.rr : cheerio.load(html); - let ret = eleFind ? ($(html.ele).is(parse) ? html.ele : $(html.ele).find(parse)) : $(parse); - let result = []; - // print('outerHTML:'); - // print($(ret[0]).prop("outerHTML")); - if (ret) { - ret.each(function (idx, ele) { - result.push({ rr: $, ele: ele }); - // result.push({ rr: $, ele: $(ele).prop("outerHTML")}); // 性能贼差 - }); - } - return result; - }, - pd(html,parse,uri){ - return parseTags.jq.pdfh(html, parse, MY_URL); - }, - }, - getParse(p0){//非js开头的情况自动获取解析标签 - 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; - -/*** 后台需要实现的java方法并注入到js中 ***/ - -/** - * 读取本地文件->应用程序目录 - * @param filePath - * @returns {string} - */ -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 -} - -/** - * 处理返回的json数据 - * @param html - * @returns {*} - */ -function dealJson(html) { - try { - // html = html.match(/[\w|\W|\s|\S]*?(\{[\w|\W|\s|\S]*\})/).group[1]; - 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) {} - // console.log(typeof(html)); - return html; -} - -/** - * 验证码识别逻辑,需要java实现(js没有bytes类型,无法调用后端的传递图片二进制获取验证码文本的接口) - * @type {{api: string, classification: (function(*=): string)}} - */ -var OcrApi={ - api:OCR_API, - classification:function (img){ // img是byte类型,这里不方便搞啊 - let code = ''; - try { - // let html = request(this.api,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true); - // html = JSON.parse(html); - // code = html.url||''; - log('通过drpy_ocr验证码接口过验证...'); - let html = request(OCR_API,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true); - code = html||''; - }catch (e) {} - return code - } -}; -/** - * 验证码识别,暂未实现 - * @param url 验证码图片链接 - * @returns {string} 验证成功后的cookie - */ -function verifyCode(url){ - let cnt = 0; - let host = getHome(url); - let cookie = ''; - while (cnt < OCR_RETRY){ - try{ - // let obj = {headers:headers,timeout:timeout}; - let yzm_url = `${host}/index.php/verify/index.html`; - console.log(`验证码链接:${yzm_url}`); - let hhtml = request(yzm_url,{withHeaders:true,toBase64:true},true); - let json = JSON.parse(hhtml); - if(!cookie){ - // print(json); - let setCk = Object.keys(json).find(it=>it.toLowerCase()==='set-cookie'); - // cookie = json['set-cookie']?json['set-cookie'].split(';')[0]:''; - cookie = setCk?json[setCk].split(';')[0]:''; - } - // console.log(hhtml); - console.log('cookie:'+cookie); - let img = json.body; - // console.log(img); - 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,'User-Agent':MOBILE_UA},'method':'POST'}); - // console.log(html); - html = JSON.parse(html); - if(html.msg === 'ok'){ - console.log(`第${cnt+1}次验证码提交成功`); - return cookie // 需要返回cookie - }else if(html.msg!=='ok'&&cnt+1>=OCR_RETRY){ - cookie = ''; // 需要清空返回cookie - } - }catch (e) { - console.log(`第${cnt+1}次验证码提交失败:${e.message}`); - if(cnt+1>=OCR_RETRY){ - cookie = ''; - } - } - cnt+=1 - } - return cookie -} - -/** - * 存在数据库配置表里, key字段对应值value,没有就新增,有就更新,调用此方法会清除key对应的内存缓存 - * @param k 键 - * @param v 值 - */ -function setItem(k,v){ - local.set(RKEY,k,v); - console.log(`规则${RKEY}设置${k} => ${v}`) -} - -/** - * 获取数据库配置表对应的key字段的value,没有这个key就返回value默认传参.需要有缓存,第一次获取后会存在内存里 - * @param k 键 - * @param v 值 - * @returns {*} - */ -function getItem(k,v){ - return local.get(RKEY,k) || v; -} - -/** - * 删除数据库key对应的一条数据,并清除此key对应的内存缓存 - * @param k - */ -function clearItem(k){ - local.delete(RKEY,k); -} - -/*** js自封装的方法 ***/ - -/** - * 获取链接的host(带http协议的完整链接) - * @param url 任意一个正常完整的Url,自动提取根 - * @returns {string} - */ -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 -} - -/** - * get参数编译链接,类似python params字典自动拼接 - * @param url 访问链接 - * @param obj 参数字典 - * @returns {*} - */ -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 -} - -/** - * 远程依赖执行函数 - * @param url 远程js地址 - */ -function require(url){ - eval(request(url)); -} -/** - * 海阔网页请求函数完整封装 - * @param url 请求链接 - * @param obj 请求对象 {headers:{},method:'',timeout:5000,body:'',withHeaders:false} - * @param ocr_flag 标识此flag是用于请求ocr识别的,自动过滤content-type指定编码 - * @returns {string|string|DocumentFragment|*} - */ -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(!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'){ - // let data = {}; - // obj.body.split('&').forEach(it=>{ - // data[it.split('=')[0]] = it.split('=')[1] - // }); - // obj.data = data; - // delete obj.body - - // 传body加 "Content-Type":"application/x-www-form-urlencoded;" 即可post form - 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){ // 返回base64,用于请求图片 - obj.buffer = 2; - delete obj.toBase64 - } - console.log(JSON.stringify(obj.headers)); - // console.log('request:'+url+' obj:'+JSON.stringify(obj)); - console.log('request:'+url+`|method:${obj.method||'GET'}|body:${obj.body||''}`); - let res = req(url, obj); - let html = res.content||''; - // console.log(html); - if(obj.withHeaders){ - let htmlWithHeaders = res.headers; - htmlWithHeaders.body = html; - return JSON.stringify(htmlWithHeaders); - }else{ - return html - } -} - -/** - * 快捷post请求 - * @param url 地址 - * @param obj 对象 - * @returns {string|DocumentFragment|*} - */ -function post(url,obj){ - obj.method = 'POST'; - return request(url,obj); -} - -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('print:'+e.message); - 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; -/** - * 检查宝塔验证并自动跳过获取正确源码 - * @param html 之前获取的html - * @param url 之前的来源url - * @param obj 来源obj - * @returns {string|DocumentFragment|*} - */ -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 -} - -/** - * 带一次宝塔验证的源码获取 - * @param url 请求链接 - * @param obj 请求参数 - * @returns {string|DocumentFragment} - */ -function getCode(url,obj){ - let html = request(url,obj); - html = checkHtml(html,url,obj); - return html -} - -/** - * 源rule专用的请求方法,自动注入cookie - * @param url 请求链接 - * @returns {string|DocumentFragment} - */ -function getHtml(url){ - let obj = {}; - if(rule.headers){ - obj.headers = rule.headers; - } - let cookie = getItem(RULE_CK,''); - if(cookie){ - // log('有cookie:'+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 -} - -/** - * 首页分类解析,筛选暂未实现 - * @param homeObj 首页传参对象 - * @returns {string} - */ -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; i < cnt; i++) { - classes.push({ - 'type_id': urls[i], - 'type_name': names[i] - }); - } - } - - if (homeObj.class_parse) { - let p = homeObj.class_parse.split(';'); - let _ps = parseTags.getParse(p[0]); - _pdfa = _ps.pdfa; - _pdfh = _ps.pdfh; - _pd = _ps.pd; - MY_URL = rule.url; - if (p.length >= 3) { // 可以不写正则 - try { - let html = getHtml(homeObj.MY_URL); - if (html) { - homeHtmlCache = html; - let list = _pdfa(html, p[0]); - 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 = pdfh(it, p[2]); - let url = _pd(it, p[2]); - if (p.length > 3 && p[3]) { - 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); - -} - -/** - * 推荐和搜索单字段继承一级 - * @param p 推荐或搜索的解析分割;列表 - * @param pn 自身列表序号 - * @param pp 一级解析分割;列表 - * @param ppn 继承一级序号 - * @returns {*} - */ -function getPP(p, pn, pp, ppn){ - try { - let ps = p[pn] === '*' && pp.length > ppn ?pp[ppn]:p[pn] - return ps - }catch (e) { - return '' - } -} - -/** - * 首页推荐列表解析 - * @param homeVodObj - * @returns {string} - */ -function homeVodParse(homeVodObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - MY_URL = homeVodObj.homeUrl; - // setItem('MY_URL',MY_URL); - 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.一级.split(';'); - if(p.startsWith('js:')){ - const TYPE = 'home'; - var input = MY_URL; - const 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:)/,''); - // print(p[0]); - let html = homeHtmlCache || getHtml(MY_URL); - homeHtmlCache = undefined; - if(is_json){ - // print('是json,开始处理'); - html = dealJson(html); - } - try { - console.log('double:' + homeVodObj.double); - if (homeVodObj.double) { - let items = _pdfa(html, p0); - // console.log(items.length); - 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) { - // console.log(p[1]); - let items2 = _pdfa(item, p1); - // console.log(items2.length); - 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 - }; - // print(vod); - 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) { - - } - - } - - } - - } catch (e) { - - } - } - let t2 = (new Date()).getTime(); - console.log('加载首页推荐耗时:'+(t2-t1)+'毫秒'); - // console.log(JSON.stringify(d)); - 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 - }) -} - -/** - * 一级分类页数据解析 - * @param cateObj - * @returns {string} - */ -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).replaceAll('fypage', cateObj.pg); - 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); - } - // console.log('filter:'+cateObj.filter); - 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'){ - // 引用传递转值传递,避免污染self变量 - 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}); - // console.log('jinjia2执行后的new_url类型为:'+typeof(new_url)); - if(/object Object/.test(new_url)){ - new_url = drT.renderText(url,fl); - } - url = new_url; - } - if(/fypage/.test(url)){ - if(url.includes('(')&&url.includes(')')){ - let url_rep = url.match(/.*?\((.*)\)/)[1]; - // console.log(url_rep); - let cnt_page = url_rep.replaceAll('fypage', cateObj.pg); - // console.log(cnt_page); - let cnt_pg = eval(cnt_page); - // console.log(cnt_pg); - url = url.replaceAll(url_rep,cnt_pg).replaceAll('(','').replaceAll(')',''); - }else{ - url = url.replaceAll('fypage',cateObj.pg); - } - } - - MY_URL = url; - // setItem('MY_URL',MY_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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - 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, - }); - // print(vod); - return vod -} - -/** - * 搜索列表数据解析 - * @param searchObj - * @returns {string} - */ -function searchParse(searchObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - if(!searchObj.searchUrl){ - return '{}' - } - let p = searchObj.搜索==='*'&&rule.一级 ? rule.一级 : searchObj.搜索; - if(!p||typeof(p)!=='string'){ - return '{}' - } - p = p.trim(); - let pp = rule.一级.split(';'); - let url = searchObj.searchUrl.replaceAll('**', searchObj.wd).replaceAll('fypage', searchObj.pg); - MY_URL = url; - console.log(MY_URL); - // log(searchObj.搜索); - // setItem('MY_URL',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:)/,''); - // print('1381 p0:'+p0); - 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 new_dict = {}; - // let new_tmp = params.split('&'); - // new_tmp.forEach(i=>{ - // new_dict[i.split('=')[0]] = i.split('=')[1]; - // }); - // html = post(rurl,{body:new_dict}); - 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) { - if(/系统安全验证|输入验证码/.test(html)){ - let cookie = verifyCode(MY_URL); - if(cookie){ - console.log(`本次成功过验证,cookie:${cookie}`); - setItem(RULE_CK,cookie); - }else{ - console.log(`本次自动过搜索验证失败,cookie:${cookie}`); - } - // obj.headers['Cookie'] = cookie; - html = getHtml(MY_URL); - } - if(!html.includes(searchObj.wd)){ - console.log('搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码'); - console.log(html); - } - if(is_json){ - // console.log(html); - html = dealJson(html); - // console.log(JSON.stringify(html)); - } - // console.log(html); - let list = _pdfa(html, p0); - // print(list.length); - // print(list); - 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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - return JSON.stringify({ - 'page': parseInt(searchObj.pg), - 'pagecount': 10, - 'limit': 20, - 'total': 100, - 'list': d, - }); -} - -/** - * 二级详情页数据解析 - * @param detailObj - * @returns {string} - */ -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.二级==='*'){ - // vod_id = orId.split('@@')[0]; // 千万不能分割 - let extra = orId.split('@@'); - vod_name = extra.length>1?extra[1]:vod_name; - vod_pic = extra.length>2?extra[2]:vod_pic; - } - // print(vod_pic); - let vod = { - vod_id: vod_id, //"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}`) - } - } - // console.log(MY_URL); - // setItem('MY_URL',MY_URL); - 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 _impJQP = false; - 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; - // print('二级默认jsp'); - // _ps = parseTags.jsp; - } - if(_ps === parseTags.jq){ // jquery解析提前load(html) - _impJQP = true; - } - if (_impJQP) { - let ttt1 = (new Date()).getTime(); - let c$ = cheerio.load(html); - // print(`二级${MY_URL}仅c$源码耗时:${(new Date()).getTime()-ttt1}毫秒`); - html = { rr: c$, ele: c$('html')[0] }; - print(`二级${MY_URL}仅cheerio.load源码耗时:${(new Date()).getTime()-ttt1}毫秒`); - } - 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]).replaceAll('\n', ' ').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 (_impJQP) { - let c$ = cheerio.load(html); - html = { rr: c$, ele: c$('html')[0] } - } - } - -// console.log(2); - if(p.tabs){ - if(p.tabs.startsWith('js:')){ - print('开始执行tabs代码:'+p.tabs); - if(html&&_impJQP&&typeof (html)!=='string'){ - try { // 假装是jq的对象拿来转换一下字符串,try为了防止json的情况报错 - html = html.rr(html.ele).toString(); - }catch (e) {} - } - var input = MY_URL; - eval(p.tabs.replace('js:','')); - playFrom = TABS; - }else{ - let p_tab = p.tabs.split(';')[0]; - // console.log(p_tab); - let vHeader = _pdfa(html, p_tab); - console.log(vHeader.length); - let tab_text = p.tab_text||'body&&Text'; - // print('tab_text:'+tab_text); - let new_map = {}; - for(let v of vHeader){ - let v_title = _pdfh(v,tab_text).trim(); - 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); - -// console.log(3); - let vod_play_url = '$$$'; - let vod_tab_list = []; - if(p.lists){ - if(p.lists.startsWith('js:')){ - print('开始执行lists代码:'+p.lists); - try { - if(html&&_impJQP&&typeof (html)!=='string'){ - // 假装是jq的对象拿来转换一下字符串,try为了防止json的情况报错 - try { - html = html.rr(html.ele).toString(); - }catch (e) {} - } - var input = MY_URL; - var play_url = ''; - eval(p.lists.replace('js:','')); - for(let i in LISTS){ - if(LISTS.hasOwnProperty(i)){ - // print(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'; - // print('list_text:'+list_text); - // print('list_url:'+list_url); - // print('list_parse:'+p.lists); - let is_tab_js = p.tabs.trim().startsWith('js:'); - for(let i=0;i 1 && !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); - // 测试jsp提速 - // console.log(p1); - // p1 = p1.replace(':eq(0)',',0').replace(' ','&&'); - // console.log(p1); - // console.log(html); - let vodList = []; - try { - vodList = _pdfa(html, p1); - console.log('len(vodList):'+vodList.length); - }catch (e) { - // console.log(e.message); - } - let new_vod_list = []; - // print('tab_ext:'+tab_ext); - let tabName = tab_ext?_pdfh(html, tab_ext):tab_name; - console.log(tabName); - // console.log('cheerio解析Text'); - // 此处存在性能问题: pt版2000集需要650毫秒,俊版1300毫秒 特么的优化不动 主要后面定位url的我拿他没法 - // 主要性能问题在于 _pd(it, list_url, MY_URL) - let tt1 = (new Date()).getTime(); - // vodList.forEach((it,idex)=>{ - // // 请注意,这里要固定pdfh解析body&&Text,不需要下划线,没写错 - // // new_vod_list.push(pdfh(it,'body&&Text')+'$'+_pd(it,'a&&href',MY_URL)); - // // new_vod_list.push(cheerio.load(it).text()+'$'+_pd(it,'a&&href',MY_URL)); - // // new_vod_list.push(_pdfh(it, list_text).trim() + '$' + _pd(it, list_url, MY_URL)); - // // new_vod_list.push(_pdfh(it, list_text).trim() + '$' +idex); - // // new_vod_list.push(idex + '$' +_pdfh(it, list_url)); - // new_vod_list.push(_pdfh(it, list_text).trim() + '$' +_pd(it, list_url,MY_URL)); - // }); - if(vodList.length>0){ - for(let i=0;ix.split('$')[0]); - console.log(`drpy影响性能代码共计列表数循环次数:${vodList.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.图片来源 && 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}毫秒`); - // print(vod); - return JSON.stringify({ - list: [vod] - }) -} - -/** - * 判断是否需要解析 - * @param url - * @returns {number|number} - */ -function tellIsJx(url){ - try { - let is_vip = !/\.(m3u8|mp4|m4a)$/.test(url.split('?')[0]) && 是否正版(url); - return is_vip?1:0 - }catch (e) { - return 1 - } -} -/** - * 选集播放点击事件解析 - * @param playObj - * @returns {string} - */ -function playParse(playObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - MY_URL = playObj.url; - if(!/http/.test(MY_URL)){ - try { - MY_URL = base64Decode(MY_URL); - }catch (e) {} - } - MY_URL = decodeURIComponent(MY_URL); - var input = MY_URL;//注入给免嗅js - let common_play = { - parse:1, - url:input, - // url:urlencode(input), - 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.replace('js:','').trim(); - print('开始执行js免嗅=>'+lazy_code); - eval(lazy_code); - lazy_play = typeof(input) === 'object'?input:{ - parse:1, - jx:tellIsJx(input), - url:input - }; - }catch (e) { - print('js免嗅错误:'+e.message); - lazy_play = common_play; - } - }else{ - lazy_play = common_play; - } - // print('play_json:'+typeof(rule.play_json)); - // console.log(Array.isArray(rule.play_json)); - if(Array.isArray(rule.play_json) && rule.play_json.length >0){ // 数组情况判断长度大于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; - // print('开始合并:'); - // print(base_json); - lazy_play = Object.assign(lazy_play,base_json); - break; - } - } - } - }else if(rule.play_json && !Array.isArray(rule.play_json)){ // 其他情况 非[] 判断true/false - let base_json = { - jx:1, - parse:1, - }; - lazy_play = Object.assign(lazy_play,base_json); - }else if(!rule.play_json){ // 不解析传0 - 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); -} - -/** - * js源预处理特定返回对象中的函数 - * @param ext - */ - function init(ext) { - console.log('init'); - try { - // make shared jsContext happy muban不能import,不然会造成换源继承后变量被篡改 - // if (typeof (globalThis.mubanJs) === 'undefined') { - // let mubanJs = request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js', { 'User-Agent': MOBILE_UA }); - // mubanJs = mubanJs.replace('export default', '(function() {return muban;}()) // export default'); - // // console.log(mubanJs); - // globalThis.mubanJs = mubanJs; - // } - // let muban = eval(globalThis.mubanJs); - let muban = 模板.getMubans(); - if (typeof ext == 'object'){ - rule = ext; - } else if (typeof ext == 'string') { - if (ext.startsWith('http')) { - let js = request(ext,{'method':'GET'}); - if (js){ - eval(js.replace('var rule', 'rule')); - } - } else { - eval(ext.replace('var rule', 'rule')); - } - } - if (rule.模板 && muban.hasOwnProperty(rule.模板)) { - print('继承模板:'+rule.模板); - rule = Object.assign(muban[rule.模板], 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.host = (rule.host||'').rstrip('/'); - HOST = rule.host; - if(rule.hostJs){ - try { - eval(rule.hostJs); - rule.host = HOST.rstrip('/'); - }catch (e) { - console.log(`执行${rule.hostJs}获取host发生错误:`+e.message); - } - } - 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.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; - } - rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host,rule.searchUrl) : rule.searchUrl; - - rule.timeout = rule.timeout||5000; - rule.encoding = rule.编码||rule.encoding||'utf-8'; - rule.search_encoding = rule.搜索编码||rule.search_encoding||''; - rule.图片来源 = rule.图片来源||''; - rule.play_json = rule.hasOwnProperty('play_json')?rule.play_json:[]; - rule.pagecount = rule.hasOwnProperty('pagecount')?rule.pagecount:{}; - 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); - } - } - } - }catch (e) { - console.log('处理headers发生错误:'+e.message); - } - } - // print(rule.headers); - rule_fetch_params = {'headers': rule.headers||false, 'timeout': rule.timeout, 'encoding': rule.encoding}; - oheaders = rule.headers||{}; - RKEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); - pre(); // 预处理 - init_test(); - }catch (e) { - console.log('init_test发生错误:'+e.message); - } -} - -let homeHtmlCache = undefined; - -/** - * js源获取首页分类和筛选特定返回对象中的函数 - * @param filter 筛选条件字典对象 - * @returns {string} - */ -function home(filter) { - console.log("home"); - let homeObj = { - filter:rule.filter||false, - MY_URL: rule.homeUrl, - class_name: rule.class_name || '', - class_url: rule.class_url || '', - class_parse: rule.class_parse || '', - cate_exclude: rule.cate_exclude, - }; - return homeParse(homeObj); -} - -/** - * js源获取首页推荐数据列表特定返回对象中的函数 - * @param params - * @returns {string} - */ -function homeVod(params) { - console.log("homeVod"); - let homeVodObj = { - 推荐:rule.推荐, - double:rule.double, - homeUrl:rule.homeUrl, - detailUrl:rule.detailUrl - }; - return homeVodParse(homeVodObj) - // return "{}"; -} - -/** - * js源获取分类页一级数据列表特定返回对象中的函数 - * @param tid 分类id - * @param pg 页数 - * @param filter 当前选中的筛选条件 - * @param extend 扩展 - * @returns {string} - */ -function category(tid, pg, filter, extend) { - let cateObj = { - url: rule.url, - 一级: rule.一级, - tid: tid, - pg: parseInt(pg), - filter: filter, - extend: extend - }; - // console.log(JSON.stringify(extend)); - return categoryParse(cateObj) -} - -/** - * js源获取二级详情页数据特定返回对象中的函数 - * @param vod_url 一级列表中的vod_id或者是带分类的自拼接 vod_id 如 fyclass$vod_id - * @returns {string} - */ -function detail(vod_url) { - let orId = vod_url; - let fyclass = ''; - 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) -} - -/** - * js源选集按钮播放点击事件特定返回对象中的函数 - * @param flag 线路名 - * @param id 播放按钮的链接 - * @param flags 全局配置的flags是否需要解析的标识列表 - * @returns {string} - */ -function play(flag, id, flags) { - let playObj = { - url:id, - flag:flag, - flags:flags - } - return playParse(playObj); -} - -/** - * js源搜索返回的数据列表特定返回对象中的函数 - * @param wd 搜索关键字 - * @param quick 是否来自快速搜索 - * @returns {string} - */ -function search(wd, quick) { - 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, - pg: 1, - quick: quick, - }; - // console.log(JSON.stringify(searchObj)); - return searchParse(searchObj) -} - -function DRPY(){//导出函数 - return { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - } -} - -// 导出函数对象 -export default { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - DRPY:DRPY -} diff --git a/lib/drpy.min.js b/lib/drpy.min.js deleted file mode 100644 index f2832590..00000000 --- a/lib/drpy.min.js +++ /dev/null @@ -1 +0,0 @@ -import cheerio from"assets://js/lib/cheerio.min.js";import"assets://js/lib/crypto-js.js";import 模板 from"./模板.js";import{gbkTool}from"./gbk.js";function init_test(){console.log("init_test_start");console.log("当前版本号:"+VERSION);console.log(RKEY);console.log(JSON.stringify(rule));console.log("init_test_end")}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 VERSION="drpy1 3.9.41beta14 20230428";const MOBILE_UA="Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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="http://drpy.nokia.press:8028/ocr/drpy/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)$/;const SELECT_REGEX=/:eq|:lt|:gt|#/g;const SELECT_REGEX_A=/:eq|:lt|:gt/g;if(typeof Object.assign!="function"){Object.assign=function(){var target=arguments[0];for(var i=1;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=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=[];globalThis.encodeUrl=urlencode;globalThis.urlencode=urlencode;function urljoin(fromPath,nowPath){fromPath=fromPath||"";nowPath=nowPath||"";return joinUrl(fromPath,nowPath)}var urljoin2=urljoin;const defaultParser={pdfh:pdfh,pdfa:pdfa,pd(html,parse,uri){let ret=this.pdfh(html,parse);if(typeof uri==="undefined"||!uri){uri=""}if(DOM_CHECK_ATTR.test(parse)){if(/http/.test(ret)){ret=ret.substr(ret.indexOf("http"))}else{ret=urljoin(MY_URL,ret)}}return ret}};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]}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)){if(/http/.test(ret)){ret=ret.substr(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,base_url){if(!parse||!parse.trim()){return""}let eleFind=typeof html==="object";let option=undefined;if(eleFind&&parse.startsWith("body&&")){parse=parse.substr(6);if(parse.indexOf("&&")<0){option=parse.trim();parse="*=*"}}if(parse.indexOf("&&")>-1){let sp=parse.split("&&");option=sp[sp.length-1];sp.splice(sp.length-1);if(sp.length>1){for(let i in sp){if(sp.hasOwnProperty(i)){if(!SELECT_REGEX.test(sp[i])){sp[i]=sp[i]+":eq(0)"}}}}else{if(!SELECT_REGEX.test(sp[0])){sp[0]=sp[0]+":eq(0)"}}parse=sp.join(" ")}let result="";const $=eleFind?html.rr:cheerio.load(html);let ret=eleFind?parse==="*=*"||$(html.ele).is(parse)?html.ele:$(html.ele).find(parse):$(parse);if(option){if(option==="Text"){result=$(ret).text()}else if(option==="Html"){result=$(ret).html()}else{result=$(ret).attr(option);if(/style/.test(option.toLowerCase())&&/url\(/.test(result)){try{result=result.match(/url\((.*?)\)/)[1]}catch(e){}}}if(result&&base_url&&DOM_CHECK_ATTR.test(option)){if(/http/.test(result)){result=result.substr(result.indexOf("http"))}else{result=urljoin(base_url,result)}}}else{result=$(ret).toString()}return result},pdfa(html,parse){if(!parse||!parse.trim()){print("!parse");return[]}let eleFind=typeof html==="object";if(parse.indexOf("&&")>-1){let sp=parse.split("&&");for(let i in sp){if(sp.hasOwnProperty(i)){if(!SELECT_REGEX_A.test(sp[i])&&iit.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,"User-Agent":MOBILE_UA},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 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(!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}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.method="POST";return request(url,obj)}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;i=3){try{let html=getHtml(homeObj.MY_URL);if(html){homeHtmlCache=html;let list=_pdfa(html,p[0]);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]){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.一级.split(";");if(p.startsWith("js:")){const TYPE="home";var input=MY_URL;const 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){}}}}catch(e){}}let t2=(new Date).getTime();console.log("加载首页推荐耗时:"+(t2-t1)+"毫秒");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)}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});if(/object Object/.test(new_url)){new_url=drT.renderText(url,fl)}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.图片来源){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"{}"}let p=searchObj.搜索==="*"&&rule.一级?rule.一级:searchObj.搜索;if(!p||typeof p!=="string"){return"{}"}p=p.trim();let pp=rule.一级.split(";");let url=searchObj.searchUrl.replaceAll("**",searchObj.wd).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){if(/系统安全验证|输入验证码/.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.图片来源){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 _impJQP=false;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}if(_ps===parseTags.jq){_impJQP=true}if(_impJQP){let ttt1=(new Date).getTime();let c$=cheerio.load(html);html={rr:c$,ele:c$("html")[0]};print(`二级${MY_URL}仅cheerio.load源码耗时:${(new Date).getTime()-ttt1}毫秒`)}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(_impJQP){let c$=cheerio.load(html);html={rr:c$,ele:c$("html")[0]}}}if(p.tabs){if(p.tabs.startsWith("js:")){print("开始执行tabs代码:"+p.tabs);if(html&&_impJQP&&typeof html!=="string"){try{html=html.rr(html.ele).toString()}catch(e){}}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();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{if(html&&_impJQP&&typeof html!=="string"){try{html=html.rr(html.ele).toString()}catch(e){}}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 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 vodList=[];try{vodList=_pdfa(html,p1);console.log("len(vodList):"+vodList.length)}catch(e){}let new_vod_list=[];let tabName=tab_ext?_pdfh(html,tab_ext):tab_name;console.log(tabName);let tt1=(new Date).getTime();if(vodList.length>0){for(let i=0;ix.split("$")[0]);console.log(`drpy影响性能代码共计列表数循环次数:${vodList.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.图片来源&&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}毫秒`);return JSON.stringify({list:[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;if(!/http/.test(MY_URL)){try{MY_URL=base64Decode(MY_URL)}catch(e){}}MY_URL=decodeURIComponent(MY_URL);var input=MY_URL;let common_play={parse:1,url:input,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.replace("js:","").trim();print("开始执行js免嗅=>"+lazy_code);eval(lazy_code);lazy_play=typeof input==="object"?input:{parse: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 init(ext){console.log("init");try{let muban=模板.getMubans();if(typeof ext=="object"){rule=ext}else if(typeof ext=="string"){if(ext.startsWith("http")){let js=request(ext,{method:"GET"});if(js){eval(js.replace("var rule","rule"))}}else{eval(ext.replace("var rule","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.host=(rule.host||"").rstrip("/");HOST=rule.host;if(rule.hostJs){try{eval(rule.hostJs);rule.host=HOST.rstrip("/")}catch(e){console.log(`执行${rule.hostJs}获取host发生错误:`+e.message)}}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.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}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.play_json=rule.hasOwnProperty("play_json")?rule.play_json:[];rule.pagecount=rule.hasOwnProperty("pagecount")?rule.pagecount:{};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)}}}}catch(e){console.log("处理headers发生错误:"+e.message)}}rule_fetch_params={headers:rule.headers||false,timeout:rule.timeout,encoding:rule.encoding};oheaders=rule.headers||{};RKEY=typeof key!=="undefined"&&key?key:"drpy_"+(rule.title||rule.host);pre();init_test()}catch(e){console.log("init_test发生错误:"+e.message)}}let homeHtmlCache=undefined;function home(filter){console.log("home");let homeObj={filter:rule.filter||false,MY_URL:rule.homeUrl,class_name:rule.class_name||"",class_url:rule.class_url||"",class_parse:rule.class_parse||"",cate_exclude:rule.cate_exclude};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="";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){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:1,quick:quick};return searchParse(searchObj)}function DRPY(){return{init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search}}export default{init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search,DRPY:DRPY}; \ No newline at end of file diff --git a/lib/drpy.ym.js b/lib/drpy.ym.js deleted file mode 100644 index 1b367091..00000000 --- a/lib/drpy.ym.js +++ /dev/null @@ -1,4 +0,0 @@ -import './util.ym.js' -import dr from './drpy.min.js' - -__JS_SPIDER__ = dr.DRPY() \ No newline at end of file diff --git a/lib/drpy2-2838.js b/lib/drpy2-2838.js deleted file mode 100644 index 178b82d7..00000000 --- a/lib/drpy2-2838.js +++ /dev/null @@ -1,2096 +0,0 @@ -import cheerio from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/cheerio.min.js'; -import 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-js.js'; - -function init_test(){ - // console.log(typeof(CryptoJS)); - console.log("init_test_start"); - console.log("当前版本号:"+VERSION); - console.log(RKEY); - console.log(JSON.stringify(rule)); - console.log("init_test_end"); -} - -/** - * 执行预处理代码 - */ -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 { - // code里可以进行get 或者 post请求cookie并改变rule.headers 里的cookie - // 直接操作 rule_fetch_params 这个变量 .headers.Cookie - eval(code); - }catch (e) { - console.log('预处理执行失败:'+e.message); - } - } -} - -let rule = {}; -const VERSION = 'drpy2 3.7.8 20221117'; -/** 已知问题记录 - * 1.影魔的jinjia2引擎不支持 {{fl}}对象直接渲染 (有能力解决的话尽量解决下,支持对象直接渲染字符串转义,如果加了|safe就不转义)[影魔牛逼,最新的文件发现这问题已经解决了] - * Array.prototype.append = Array.prototype.push; 这种js执行后有毛病,for in 循环列表会把属性给打印出来 (这个大毛病需要重点排除一下) - * 2.import es6py.js但是里面的函数没有被装载进来.比如drpy规则报错setResult2 is undefiend(合并文件了可以不管了) - * 3.无法重复导入cheerio(怎么解决drpy和parseTag里都需要导入cheerio的问题) 无法在副文件导入cheerio (现在是全部放在drpy一个文件里了,凑合解决?) - * 4.有个错误不知道哪儿来的 executeScript: com.quickjs.JSObject$Undefined cannot be cast to java.lang.String 在 点击选集播放打印init_test_end后面打印(貌似不影响使用) - * 5.需要实现 stringify 函数,比起JSON.stringify函数,它会原封不动保留中文不会编码unicode - * 6.base64Encode,base64Decode,md5函数还没有实现 (抄影魔代码实现了) - * 7.eval(getCryptoJS());还没有实现 (可以空实现了,以后遇到能忽略) - * done: jsp:{pdfa,pdfh,pd},json:{pdfa,pdfh,pd},jq:{pdfa,pdfh,pd} - * * 电脑看日志调试 - adb tcpip 5555 - adb connect 192.168.10.192 - adb devices -l - adb logcat -c - adb logcat | grep -i QuickJS - adb logcat -c -b events - adb logcat -c -b main -b events -b radio -b system - adb logcat > 2.log DRPY:E | grep -i QuickJS - * **/ - - -/*** 以下是内置变量和解析方法 **/ -const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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'; // 源cookie的key值 -// const KEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); // 源的唯一标识 -const CATE_EXCLUDE = '首页|留言|APP|下载|资讯|新闻|动态'; -const TAB_EXCLUDE = '猜你|喜欢|APP|下载|剧情|热播'; -const OCR_RETRY = 3;//ocr验证重试次数 -// const OCR_API = 'http://dm.mudery.com:10000';//ocr在线识别接口 -// const OCR_API = 'http://192.168.3.239:5705/parse/ocr';//ocr在线识别接口 -// const OCR_API = 'http://cms.nokia.press/parse/ocr';//ocr在线识别接口 -const OCR_API = 'http://cms.nokia.press:5706/parse/ocr';//ocr在线识别接口 -if(typeof(MY_URL)==='undefined'){ - var MY_URL; // 全局注入变量,pd函数需要 -} -var RKEY; // 源的唯一标识 -var fetch; -var print; -var log; -var rule_fetch_params; -var fetch_params; // 每个位置单独的 -var oheaders; -// var play_url; // 二级详情页注入变量,为了适配js模式0 (不在这里定义了,直接二级里定义了个空字符串) -var _pdfh; -var _pdfa; -var _pd; -// const DOM_CHECK_ATTR = ['url', 'src', 'href', 'data-original', 'data-src']; -const DOM_CHECK_ATTR = /(url|src|href|-original|-src|-play|-url)$/; -const NOADD_INDEX = /:eq|:lt|:gt|:first|:last|^body$|^#/; // 不自动加eq下标索引 -const URLJOIN_ATTR = /(url|src|href|-original|-src|-play|-url)$/; // 需要自动urljoin的属性 -const SELECT_REGEX = /:eq|:lt|:gt|#/g; -const SELECT_REGEX_A = /:eq|:lt|:gt/g; - -/** - es6py扩展 - */ -if (typeof Object.assign != 'function') { - Object.assign = function () { - var target = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; -} -if (!String.prototype.includes) { - String.prototype.includes = function (search, start) { - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > this.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) {//this是空或者未定义,抛出错误 - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this);//将this转变成对象 - var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0 - - if (len === 0) {//length为0直接返回false未找到目标值 - return false; - } - - var n = fromIndex | 0;//查找起始索引 - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);//计算正确起始索引,因为有可能是负值 - - while (k < len) {//从起始索引处开始循环 - if (o[k] === searchElement) {//如果某一位置与寻找目标相等,返回true,找到了 - return true; - } - k++; - } - return false;//未找到,返回false - } - }); -} -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (prefix){ - return this.slice(0, prefix.length) === prefix; - }; -} -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function(suffix) { - return this.indexOf(suffix, this.length - suffix.length) !== -1; - }; -} -Object.prototype.myValues=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; -} -if (typeof Object.prototype.values != 'function') { - Object.prototype.values=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; - } -} -if (typeof Array.prototype.join != 'function') { - Array.prototype.join = function (emoji) { - // emoji = emoji||','; - emoji = emoji||''; - let self = this; - let str = ""; - let i = 0; - if (!Array.isArray(self)) {throw String(self)+'is not Array'} - if(self.length===0){return ''} - if (self.length === 1){return String(self[0])} - i = 1; - str = this[0]; - for (; i < self.length; i++) { - str += String(emoji)+String(self[i]); - } - return str; - }; -} - -String.prototype.rstrip = function (chars) { - let regex = new RegExp(chars + "$"); - return this.replace(regex, ""); -}; - -Array.prototype.append = Array.prototype.push; -String.prototype.strip = String.prototype.trim; -function 是否正版(vipUrl){ - let flag = new RegExp('qq\.com|iqiyi\.com|youku\.com|mgtv\.com|bilibili\.com|sohu\.com|ixigua\.com|pptv\.com|miguvideo\.com|le\.com|1905\.com|fun\.tv'); - return flag.test(vipUrl); -} -function urlDeal(vipUrl){ - if(!vipUrl){ - return '' - } - if(!是否正版(vipUrl)){ - return vipUrl - } - if(!/miguvideo/.test(vipUrl)){ - vipUrl=vipUrl.split('#')[0].split('?')[0]; - } - return vipUrl -} -function setResult(d){ - if(!Array.isArray(d)){ - return [] - } - VODS = []; - // print(d); - d.forEach(function (it){ - let obj = { - vod_id:it.url||'', - vod_name: it.title||'', - vod_remarks: it.desc||'', - vod_content: it.content||'', - vod_pic: it.pic_url||it.img||'', - }; - let keys = Object.keys(it); - if(keys.includes('tname')){ - obj.type_name = it.tname||''; - } - if(keys.includes('tid')){ - obj.type_id = it.tid||''; - } - if(keys.includes('year')){ - obj.vod_year = it.year||''; - } - if(keys.includes('actor')){ - obj.vod_actor = it.actor||''; - } - if(keys.includes('director')){ - obj.vod_director = it.director||''; - } - if(keys.includes('area')){ - obj.vod_area = it.area||''; - } - VODS.push(obj); - }); - return VODS -} -function setResult2(res){ - VODS = res.list||[]; - return VODS -} -function setHomeResult(res){ - if(!res||typeof(res)!=='object'){ - return [] - } - return setResult(res.list); -} -// 猫了个咪 -function rc(js) { - if (js === 'maomi_aes.js') { - var a = CryptoJS.enc.Utf8.parse("625222f9149e961d"); - var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330"); - return { - De: function (word) { - word = CryptoJS.enc.Hex.parse(word) - return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - }, - En: function (word) { - // print(a); - // print(word); - var Encrypted = CryptoJS.AES.encrypt(word, a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return Encrypted.ciphertext.toString(); - } - }; - } - return {}; -} - -// 千万不要用for in 推荐 forEach (for in 会打乱顺序) -//猫函数 -function maoss(jxurl, ref, key) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - eval(getCryptoJS()); - try { - var getVideoInfo = function (text) { - return CryptoJS.AES.decrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); - }; - var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key; - if (ref) { - var html = request(jxurl, { - headers: { - 'Referer': ref - } - }); - } else { - var html = request(jxurl); - } - // print(html); - if (html.indexOf('&btwaf=') != -1) { - html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], { - headers: { - 'Referer': ref - } - }) - } - var token_iv = html.split('_token = "')[1].split('"')[0]; - var key = CryptoJS.enc.Utf8.parse(token_key); - var iv = CryptoJS.enc.Utf8.parse(token_iv); - // log("iv:"+iv); - // log(html); - // print(key); - // print(iv); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - // config.url = config.url.replace(/,/g,''); - // print(config.url); - if (!config.url.startsWith('http')) { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - config.url = CryptoJS.AES.decrypt(config.url, key, { - iv: iv, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - } - return config.url; - } catch (e) { - return ''; - } -} - -function urlencode (str) { - str = (str + '').toString(); - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28'). - replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); -} - -function base64Encode(text){ - return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)); - // return text -} - -function base64Decode(text){ - return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text)); - // return text -} - -function md5(text) { - return CryptoJS.MD5(text).toString(); -} - -function getCryptoJS(){ - // return request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-hiker.js'); - return 'console.log("CryptoJS已装载");' -} - -let VODS = [];// 一级或者搜索需要的数据列表 -let VOD = {};// 二级的单个数据 -let TABS = [];// 二级的自定义线路列表 如: TABS=['道长在线','道长在线2'] -let LISTS = [];// 二级的自定义选集播放列表 如: LISTS=[['第1集$http://1.mp4','第2集$http://2.mp4'],['第3集$http://1.mp4','第4集$http://2.mp4']] -globalThis.encodeUrl = urlencode; -globalThis.urlencode = urlencode; - - - -/** - * url拼接 - * @param fromPath 初始当前页面url - * @param nowPath 相对当前页面url - * @returns {*} - */ -function urljoin(fromPath, nowPath) { - fromPath = fromPath||''; - nowPath = nowPath||''; - return joinUrl(fromPath, nowPath); - // try { - // // import Uri from './uri.min.js'; - // // var Uri = require('./uri.min.js'); - // // eval(request('https://cdn.bootcdn.net/ajax/libs/URI.js/1.19.11/URI.min.js')); - // // let new_uri = URI(nowPath, fromPath); - - // let new_uri = Uri(nowPath, fromPath); - // new_uri = new_uri.toString(); - // // console.log(new_uri); - // // return fromPath + nowPath - // return new_uri - // } - // catch (e) { - // console.log('urljoin发生错误:'+e.message); - // if(nowPath.startsWith('http')){ - // return nowPath - // }if(nowPath.startsWith('/')){ - // return getHome(fromPath)+nowPath - // } - // return fromPath+nowPath - // } -} -var urljoin2 = urljoin; - -// 内置 pdfh,pdfa,pd -const defaultParser = { - pdfh:pdfh, - pdfa:pdfa, - parseHikerToJq(parse,first){ - // 海阔解析表达式转原生表达式,自动补eq,如果传了first就最后一个也取eq(0) - first = first||false; - if(parse.includes('&&')){ - parse = parse.split('&&'); //带&&的重新拼接 - let new_parses = []; // 构造新的解析表达式列表 - parse.forEach((it,i)=>{ - let ps = it.split(' ').slice(-1)[0]; // 如果分割&&后带空格就取最后一个元素 - if(!NOADD_INDEX.test(ps)){ - if(!first&&i>=parse.length-1){ - new_parses.push(it); - }else{ - new_parses.push(`${it}:eq(0)`); - } - }else{ - new_parses.push(it); - } - }); - parse = new_parses.join(' '); - }else{ - let ps = parse.split(' ').slice(-1)[0]; // 如果带空格就取最后一个元素 - if(!NOADD_INDEX.test(ps) && first){ - parse = `${parse}:eq(0)`; - } - } - return parse; - }, - pd(html,parse,uri){ - let ret = this.pdfh(html,parse); - if(typeof(uri)==='undefined'||!uri){ - uri = ''; - } - if(DOM_CHECK_ATTR.test(parse)){ - if(/http/.test(ret)){ - ret = ret.substr(ret.indexOf('http')); - }else{ - ret = urljoin(MY_URL,ret) - } - } - return ret - }, -}; - - -/** - * pdfh原版优化,能取style属性里的图片链接 - * @param html 源码 - * @param parse 解析表达式 - * @returns {string|*} - */ -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]; - }catch (e) {} - } - return result -} - -/** - * pdfa原版优化,可以转换jq的html对象 - * @param html - * @param parse - * @returns {*} - */ -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); -} - -/** - * pd原版方法重写-增加自动urljoin - * @param html - * @param parse - * @param uri - * @returns {*} - */ -function pd2(html,parse,uri){ - let ret = pdfh2(html,parse); - if(typeof(uri)==='undefined'||!uri){ - uri = ''; - } - if(DOM_CHECK_ATTR.test(parse)){ - if(/http/.test(ret)){ - ret = ret.substr(ret.indexOf('http')); - }else{ - ret = urljoin(MY_URL,ret) - } - } - // MY_URL = getItem('MY_URL',MY_URL); - // console.log(`规则${RKEY}打印MY_URL:${MY_URL},uri:${uri}`); - return ret -} - -const parseTags = { - jsp:{ - pdfh:pdfh2, - pdfa:pdfa2, - pd:pd2, - }, - json:{ - pdfh(html, parse) { - if (!parse || !parse.trim()){ - return ''; - } - if (typeof(html) === 'string'){ - // print('jsonpath:pdfh字符串转dict'); - 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'){ - // print('jsonpath:pdfa字符串转dict'); - 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, base_url) { - if (!html||!parse || !parse.trim()) { - return '' - } - parse = parse.trim(); - let reparse = ['body&&Text','Text','body&&Html','Html']; - if(reparse.includes(reparse)){ - return defaultParser.pdfh(html,parse) - } - let option = ''; - if(parse.includes('&&')){ - option = parse.split('&&').slice(-1)[0]; - parse = parse.split('&&').slice(0,-1).join('&&'); - } - parse = defaultParser.parseHikerToJq(parse, true); - let result = defaultParser.pdfh(html,parse,option); - if(option&&/style/.test(option.toLowerCase())&&/url\(/.test(result)){ - try { - result = result.match(/url\((.*?)\)/)[1]; - // print(result); - }catch (e) {} - } - if (result && base_url && option && DOM_CHECK_ATTR.test(option)) { - if (/http/.test(result)) { - result = result.substr(result.indexOf('http')); - } else { - result = urljoin(base_url, result) - } - // print(result); - } - return result; - }, - pdfa(html, parse) { - if (!html||!parse || !parse.trim()) { - return []; - } - parse = parse.trim(); - parse = defaultParser.parseHikerToJq(parse) - let result = defaultParser.pdfa(html,parse); - // print(result); - print(`pdfa解析${parse}=>${result.length}`); - return result; - }, - pd(html,parse,uri){ - return parseTags.jq.pdfh(html, parse, MY_URL); - }, - }, - getParse(p0){//非js开头的情况自动获取解析标签 - 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; - -/*** 后台需要实现的java方法并注入到js中 ***/ - -/** - * 读取本地文件->应用程序目录 - * @param filePath - * @returns {string} - */ -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 -} - -/** - * 处理返回的json数据 - * @param html - * @returns {*} - */ -function dealJson(html) { - try { - // html = html.match(/[\w|\W|\s|\S]*?(\{[\w|\W|\s|\S]*\})/).group[1]; - 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) {} - // console.log(typeof(html)); - return html; -} - -/** - * 验证码识别逻辑,需要java实现(js没有bytes类型,无法调用后端的传递图片二进制获取验证码文本的接口) - * @type {{api: string, classification: (function(*=): string)}} - */ -var OcrApi={ - api:OCR_API, - classification:function (img){ // img是byte类型,这里不方便搞啊 - let code = ''; - try { - let html = request(this.api,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true); - html = JSON.parse(html); - code = html.url||''; - }catch (e) {} - return code - } -}; -/** - * 验证码识别,暂未实现 - * @param url 验证码图片链接 - * @returns {string} 验证成功后的cookie - */ -function verifyCode(url){ - let cnt = 0; - let host = getHome(url); - let cookie = ''; - while (cnt < OCR_RETRY){ - try{ - // let obj = {headers:headers,timeout:timeout}; - let yzm_url = `${host}/index.php/verify/index.html`; - console.log(`验证码链接:${yzm_url}`); - let hhtml = request(yzm_url,{withHeaders:true,toBase64:true},true); - let json = JSON.parse(hhtml); - if(!cookie){ - // print(json); - let setCk = Object.keys(json).find(it=>it.toLowerCase()==='set-cookie'); - // cookie = json['set-cookie']?json['set-cookie'].split(';')[0]:''; - cookie = setCk?json[setCk].split(';')[0]:''; - } - // console.log(hhtml); - console.log('cookie:'+cookie); - let img = json.body; - // console.log(img); - 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,'User-Agent':MOBILE_UA},'method':'POST'}); - // console.log(html); - html = JSON.parse(html); - if(html.msg === 'ok'){ - console.log(`第${cnt+1}次验证码提交成功`); - return cookie // 需要返回cookie - }else if(html.msg!=='ok'&&cnt+1>=OCR_RETRY){ - cookie = ''; // 需要清空返回cookie - } - }catch (e) { - console.log(`第${cnt+1}次验证码提交失败:${e.message}`); - if(cnt+1>=OCR_RETRY){ - cookie = ''; - } - } - cnt+=1 - } - return cookie -} - -/** - * 存在数据库配置表里, key字段对应值value,没有就新增,有就更新,调用此方法会清除key对应的内存缓存 - * @param k 键 - * @param v 值 - */ -function setItem(k,v){ - local.set(RKEY,k,v); - console.log(`规则${RKEY}设置${k} => ${v}`) -} - -/** - * 获取数据库配置表对应的key字段的value,没有这个key就返回value默认传参.需要有缓存,第一次获取后会存在内存里 - * @param k 键 - * @param v 值 - * @returns {*} - */ -function getItem(k,v){ - return local.get(RKEY,k) || v; -} - -/** - * 删除数据库key对应的一条数据,并清除此key对应的内存缓存 - * @param k - */ -function clearItem(k){ - local.delete(RKEY,k); -} - -/*** js自封装的方法 ***/ - -/** - * 获取链接的host(带http协议的完整链接) - * @param url 任意一个正常完整的Url,自动提取根 - * @returns {string} - */ -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 -} - -/** - * get参数编译链接,类似python params字典自动拼接 - * @param url 访问链接 - * @param obj 参数字典 - * @returns {*} - */ -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 -} - -/** - * 远程依赖执行函数 - * @param url 远程js地址 - */ -function require(url){ - eval(request(url)); -} -/** - * 海阔网页请求函数完整封装 - * @param url 请求链接 - * @param obj 请求对象 {headers:{},method:'',timeout:5000,body:'',withHeaders:false} - * @param ocr_flag 标识此flag是用于请求ocr识别的,自动过滤content-type指定编码 - * @returns {string|string|DocumentFragment|*} - */ -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(!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'){ - let data = {}; - obj.body.split('&').forEach(it=>{ - data[it.split('=')[0]] = it.split('=')[1] - }); - obj.data = data; - delete obj.body - }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){ // 返回base64,用于请求图片 - obj.buffer = 2; - delete obj.toBase64 - } - console.log(JSON.stringify(obj.headers)); - // console.log('request:'+url+' obj:'+JSON.stringify(obj)); - console.log('request:'+url); - let res = req(url, obj); - let html = res.content||''; - // console.log(html); - if(obj.withHeaders){ - let htmlWithHeaders = res.headers; - htmlWithHeaders.body = html; - return JSON.stringify(htmlWithHeaders); - }else{ - return html - } -} - -/** - * 快捷post请求 - * @param url 地址 - * @param obj 对象 - * @returns {string|DocumentFragment|*} - */ -function post(url,obj){ - obj.method = 'POST'; - return request(url,obj); -} - -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('print:'+e.message); - 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; -/** - * 检查宝塔验证并自动跳过获取正确源码 - * @param html 之前获取的html - * @param url 之前的来源url - * @param obj 来源obj - * @returns {string|DocumentFragment|*} - */ -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 -} - -/** - * 带一次宝塔验证的源码获取 - * @param url 请求链接 - * @param obj 请求参数 - * @returns {string|DocumentFragment} - */ -function getCode(url,obj){ - let html = request(url,obj); - html = checkHtml(html,url,obj); - return html -} - -/** - * 源rule专用的请求方法,自动注入cookie - * @param url 请求链接 - * @returns {string|DocumentFragment} - */ -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')){ - obj.headers['Cookie'] = cookie; - }else if(!obj.headers){ - obj.headers = {Cookie:cookie}; - } - } - let html = getCode(url,obj); - return html -} - -/** - * 首页分类解析,筛选暂未实现 - * @param homeObj 首页传参对象 - * @returns {string} - */ -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; i < cnt; i++) { - classes.push({ - 'type_id': urls[i], - 'type_name': names[i] - }); - } - } - - if (homeObj.class_parse) { - let p = homeObj.class_parse.split(';'); - let _ps = parseTags.getParse(p[0]); - _pdfa = _ps.pdfa; - _pdfh = _ps.pdfh; - _pd = _ps.pd; - MY_URL = rule.url; - if (p.length >= 3) { // 可以不写正则 - try { - let html = getHtml(homeObj.MY_URL); - if (html) { - homeHtmlCache = html; - let list = _pdfa(html, p[0]); - 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 = pdfh(it, p[2]); - let url = _pd(it, p[2]); - if (p.length > 3 && p[3]) { - 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); - -} - -/** - * 推荐和搜索单字段继承一级 - * @param p 推荐或搜索的解析分割;列表 - * @param pn 自身列表序号 - * @param pp 一级解析分割;列表 - * @param ppn 继承一级序号 - * @returns {*} - */ -function getPP(p, pn, pp, ppn){ - let ps = p[pn] === '*' && pp.length > ppn ?pp[ppn]:p[pn] - return ps -} - -/** - * 首页推荐列表解析 - * @param homeVodObj - * @returns {string} - */ -function homeVodParse(homeVodObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - MY_URL = homeVodObj.homeUrl; - // setItem('MY_URL',MY_URL); - 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.一级.split(';'); - if(p.startsWith('js:')){ - const TYPE = 'home'; - var input = MY_URL; - const 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:)/,''); - // print(p[0]); - let html = homeHtmlCache || getHtml(MY_URL); - homeHtmlCache = undefined; - if(is_json){ - // print('是json,开始处理'); - html = dealJson(html); - } - try { - console.log('double:' + homeVodObj.double); - if (homeVodObj.double) { - let items = _pdfa(html, p0); - // console.log(items.length); - for (let item of items) { - // console.log(p[1]); - let items2 = _pdfa(item, p[1]); - // console.log(items2.length); - for (let item2 of items2) { - try { - let p2 = getPP(p,2,pp,1); - let title = _pdfh(item2, p2); - let img = ''; - try { - let p3 = getPP(p,3,pp,2); - img = _pd(item2, p3); - } catch (e) {} - let desc = ''; - try { - let p4 = getPP(p,4,pp,3); - desc = _pdfh(item2, p4); - }catch (e) {} - let p5 = getPP(p,5,pp,4); - 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]){ - let p6 = getPP(p,6,pp,5); - 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 - }; - // print(vod); - d.push(vod); - } catch (e) { - console.log('首页列表双层定位处理发生错误:'+e.message); - } - - } - - - } - - - } else { - let items = _pdfa(html, p0); - for (let item of items) { - try { - let p1 = getPP(p,1,pp,1); - let title = _pdfh(item, p1); - let img = ''; - try { - let p2 = getPP(p,2,pp,2); - img = _pd(item, p2, MY_URL); - } catch (e) {} - let desc = ''; - try { - let p3 = getPP(p,3,pp,3); - desc = _pdfh(item, p3); - }catch (e) {} - let p4 = getPP(p,4,pp,4); - 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]){ - let p5 = getPP(p,5,pp,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)+'毫秒'); - // console.log(JSON.stringify(d)); - if(rule.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - return JSON.stringify({ - list:d - }) -} - -/** - * 一级分类页数据解析 - * @param cateObj - * @returns {string} - */ -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).replaceAll('fypage', cateObj.pg); - let url = cateObj.url.replaceAll('fyclass', cateObj.tid); - 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); - } - // console.log('filter:'+cateObj.filter); - 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'){ - // 引用传递转值传递,避免污染self变量 - 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}); - // console.log('jinjia2执行后的new_url类型为:'+typeof(new_url)); - url = new_url; - } - if(/fypage/.test(url)){ - if(url.includes('(')&&url.includes(')')){ - let url_rep = url.match(/.*?\((.*)\)/)[1]; - // console.log(url_rep); - let cnt_page = url_rep.replaceAll('fypage', cateObj.pg); - // console.log(cnt_page); - let cnt_pg = eval(cnt_page); - // console.log(cnt_pg); - url = url.replaceAll(url_rep,cnt_pg).replaceAll('(','').replaceAll(')',''); - }else{ - url = url.replaceAll('fypage',cateObj.pg); - } - } - 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]; - } - MY_URL = url; - // setItem('MY_URL',MY_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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - return d.length<1?'{}':JSON.stringify({ - 'page': parseInt(cateObj.pg), - 'pagecount': 999, - 'limit': 20, - 'total': 999, - 'list': d, - }); -} - -/** - * 搜索列表数据解析 - * @param searchObj - * @returns {string} - */ -function searchParse(searchObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - if(!searchObj.searchUrl){ - return '{}' - } - let p = searchObj.搜索==='*'&&rule.一级 ? rule.一级 : searchObj.搜索; - if(!p||typeof(p)!=='string'){ - return '{}' - } - p = p.trim(); - let pp = rule.一级.split(';'); - let url = searchObj.searchUrl.replaceAll('**', searchObj.wd).replaceAll('fypage', searchObj.pg); - MY_URL = url; - console.log(MY_URL); - // log(searchObj.搜索); - // setItem('MY_URL',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:)/,''); - // print('1381 p0:'+p0); - try { - let html = getHtml(MY_URL); - if (html) { - if(/系统安全验证|输入验证码/.test(html)){ - let cookie = verifyCode(MY_URL); - if(cookie){ - console.log(`本次成功过验证,cookie:${cookie}`); - setItem(RULE_CK,cookie); - }else{ - console.log(`本次自动过搜索验证失败,cookie:${cookie}`); - } - // obj.headers['Cookie'] = cookie; - html = getHtml(MY_URL); - } - if(!html.includes(searchObj.wd)){ - console.log('搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码'); - console.log(html); - } - if(is_json){ - // console.log(html); - html = dealJson(html); - // console.log(JSON.stringify(html)); - } - // console.log(html); - let list = _pdfa(html, p0); - // print(list.length); - // print(list); - list.forEach(it => { - 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 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]){ - let p5 = getPP(p,5,pp,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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - return JSON.stringify({ - 'page': parseInt(searchObj.pg), - 'pagecount': 10, - 'limit': 20, - 'total': 100, - 'list': d, - }); -} - -/** - * 二级详情页数据解析 - * @param detailObj - * @returns {string} - */ -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.二级==='*'){ - // vod_id = orId.split('@@')[0]; // 千万不能分割 - let extra = orId.split('@@'); - vod_name = extra.length>1?extra[1]:vod_name; - vod_pic = extra.length>2?extra[2]:vod_pic; - } - // print(vod_pic); - let vod = { - vod_id: vod_id, //"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; - // console.log(MY_URL); - // setItem('MY_URL',MY_URL); - 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; - // print('二级默认jsp'); - // _ps = parseTags.jsp; - } - 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]).replaceAll('\n', ' ').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:','')); - } - -// console.log(2); - 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]; - // console.log(p_tab); - let vHeader = _pdfa(html, p_tab); - console.log(vHeader.length); - let tab_text = p.tab_text||'body&&Text'; - // print('tab_text:'+tab_text); - for(let v of vHeader){ - let v_title = _pdfh(v,tab_text).trim(); - console.log(v_title); - if(tab_exclude&& (new RegExp(tab_exclude)).test(v_title)){ - continue; - } - playFrom.push(v_title); - } - } - console.log(JSON.stringify(playFrom)); - }else{ - playFrom = ['道长在线'] - } - vod.vod_play_from = playFrom.join(vod_play_from); - -// console.log(3); - 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)){ - // print(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'; - // print('list_text:'+list_text); - // print('list_url:'+list_url); - // print('list_parse:'+p.lists); - let is_tab_js = p.tabs.trim().startsWith('js:'); - for(let i=0;i 1 && !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); - // 测试jsp提速 - // console.log(p1); - // p1 = p1.replace(':eq(0)',',0').replace(' ','&&'); - // console.log(p1); - // console.log(html); - let vodList = []; - try { - vodList = _pdfa(html, p1); - console.log('len(vodList):'+vodList.length); - }catch (e) { - // console.log(e.message); - } - let new_vod_list = []; - // print('tab_ext:'+tab_ext); - let tabName = tab_ext?_pdfh(html, tab_ext):tab_name; - console.log(tabName); - // console.log('cheerio解析Text'); - // 此处存在性能问题: pt版2000集需要650毫秒,俊版1300毫秒 特么的优化不动 主要后面定位url的我拿他没法 - // 主要性能问题在于 _pd(it, list_url, MY_URL) - let tt1 = (new Date()).getTime(); - vodList.forEach((it,idex)=>{ - // 请注意,这里要固定pdfh解析body&&Text,不需要下划线,没写错 - // new_vod_list.push(pdfh(it,'body&&Text')+'$'+_pd(it,'a&&href',MY_URL)); - // new_vod_list.push(cheerio.load(it).text()+'$'+_pd(it,'a&&href',MY_URL)); - // new_vod_list.push(_pdfh(it, list_text).trim() + '$' + _pd(it, list_url, MY_URL)); - // new_vod_list.push(_pdfh(it, list_text).trim() + '$' +idex); - // new_vod_list.push(idex + '$' +_pdfh(it, list_url)); - new_vod_list.push(_pdfh(it, list_text).trim() + '$' +_pd(it, list_url,MY_URL)); - }); - if(vodList.length>0){ - console.log(`drpy影响性能代码共计列表数循环次数:${vodList.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.图片来源 && vod.vod_pic && vod.vod_pic.startsWith('http')){ - vod.vod_pic = vod.vod_pic + rule.图片来源; - } - if(!vod.vod_id){ - vod.vod_id = vod_id; - } - let t2 = (new Date()).getTime(); - console.log(`加载二级界面${MY_URL}耗时:${t2-t1}毫秒`); - // print(vod); - return JSON.stringify({ - list: [vod] - }) -} - -/** - * 判断是否需要解析 - * @param url - * @returns {number|number} - */ -function tellIsJx(url){ - try { - let is_vip = !/\.(m3u8|mp4|m4a)$/.test(url.split('?')[0]) && 是否正版(url); - return is_vip?1:0 - }catch (e) { - return 1 - } -} -/** - * 选集播放点击事件解析 - * @param playObj - * @returns {string} - */ -function playParse(playObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - MY_URL = playObj.url; - if(!/http/.test(MY_URL)){ - try { - MY_URL = base64Decode(MY_URL); - }catch (e) {} - } - MY_URL = decodeURIComponent(MY_URL); - var input = MY_URL;//注入给免嗅js - let common_play = { - parse:1, - url:input, - // url:urlencode(input), - 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.replace('js:','').trim(); - print('开始执行js免嗅=>'+lazy_code); - eval(lazy_code); - lazy_play = typeof(input) === 'object'?input:{ - parse:1, - jx:tellIsJx(input), - url:input - }; - }catch (e) { - print('js免嗅错误:'+e.message); - lazy_play = common_play; - } - }else{ - lazy_play = common_play; - } - // print('play_json:'+typeof(rule.play_json)); - // console.log(Array.isArray(rule.play_json)); - if(Array.isArray(rule.play_json) && rule.play_json.length >0){ // 数组情况判断长度大于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; - // print('开始合并:'); - // print(base_json); - lazy_play = Object.assign(lazy_play,base_json); - break; - } - } - } - }else if(rule.play_json && !Array.isArray(rule.play_json)){ // 其他情况 非[] 判断true/false - let base_json = { - jx:1, - parse:1, - }; - lazy_play = Object.assign(lazy_play,base_json); - }else if(!rule.play_json){ // 不解析传0 - 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); -} - -/** - * js源预处理特定返回对象中的函数 - * @param ext - */ -function init(ext) { - console.log('init'); - try { - // make shared jsContext happy muban不能import,不然会造成换源继承后变量被篡改 - if (typeof (globalThis.mubanJs) === 'undefined') { - let mubanJs = request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js', { 'User-Agent': MOBILE_UA }); - mubanJs = mubanJs.replace('export default', '(function() {return muban;}()) // export default'); - // console.log(mubanJs); - globalThis.mubanJs = mubanJs; - } - let muban = eval(globalThis.mubanJs); - if (typeof ext == 'object'){ - rule = ext; - } else if (typeof ext == 'string') { - if (ext.startsWith('http')) { - let js = request(ext,{'method':'GET'}); - if (js){ - eval(js.replace('var rule', 'rule')); - } - } - } else { - eval(ext.replace('var rule', 'rule')); - } - if (rule.模板 && muban.hasOwnProperty(rule.模板)) { - print('继承模板:'+rule.模板); - rule = Object.assign(muban[rule.模板], 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.host = (rule.host||'').rstrip('/'); - 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.detailUrl = rule.host&&rule.detailUrl?urljoin(rule.host,rule.detailUrl):rule.detailUrl; - 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; - } - rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host,rule.searchUrl) : rule.searchUrl; - - rule.timeout = rule.timeout||5000; - rule.encoding = rule.编码||rule.encoding||'utf-8'; - rule.图片来源 = rule.图片来源||''; - rule.play_json = rule.hasOwnProperty('play_json')?rule.play_json:[]; - 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); - } - } - } - }catch (e) { - console.log('处理headers发生错误:'+e.message); - } - } - // print(rule.headers); - rule_fetch_params = {'headers': rule.headers||false, 'timeout': rule.timeout, 'encoding': rule.encoding}; - oheaders = rule.headers||{}; - RKEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); - pre(); // 预处理 - init_test(); - }catch (e) { - console.log('init_test发生错误:'+e.message); - } -} - -let homeHtmlCache = undefined; - -/** - * js源获取首页分类和筛选特定返回对象中的函数 - * @param filter 筛选条件字典对象 - * @returns {string} - */ -function home(filter) { - console.log("home"); - let homeObj = { - filter:rule.filter||false, - MY_URL: rule.homeUrl, - class_name: rule.class_name || '', - class_url: rule.class_url || '', - class_parse: rule.class_parse || '', - cate_exclude: rule.cate_exclude, - }; - return homeParse(homeObj); -} - -/** - * js源获取首页推荐数据列表特定返回对象中的函数 - * @param params - * @returns {string} - */ -function homeVod(params) { - console.log("homeVod"); - let homeVodObj = { - 推荐:rule.推荐, - double:rule.double, - homeUrl:rule.homeUrl, - detailUrl:rule.detailUrl - }; - return homeVodParse(homeVodObj) - // return "{}"; -} - -/** - * js源获取分类页一级数据列表特定返回对象中的函数 - * @param tid 分类id - * @param pg 页数 - * @param filter 当前选中的筛选条件 - * @param extend 扩展 - * @returns {string} - */ -function category(tid, pg, filter, extend) { - let cateObj = { - url: rule.url, - 一级: rule.一级, - tid: tid, - pg: parseInt(pg), - filter: filter, - extend: extend - }; - // console.log(JSON.stringify(extend)); - return categoryParse(cateObj) -} - -/** - * js源获取二级详情页数据特定返回对象中的函数 - * @param vod_url 一级列表中的vod_id或者是带分类的自拼接 vod_id 如 fyclass$vod_id - * @returns {string} - */ -function detail(vod_url) { - let orId = vod_url; - let fyclass = ''; - 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.二级, - detailUrl:detailUrl, - fyclass:fyclass, - tab_exclude:rule.tab_exclude, - } - return detailParse(detailObj) -} - -/** - * js源选集按钮播放点击事件特定返回对象中的函数 - * @param flag 线路名 - * @param id 播放按钮的链接 - * @param flags 全局配置的flags是否需要解析的标识列表 - * @returns {string} - */ -function play(flag, id, flags) { - let playObj = { - url:id, - flag:flag, - flags:flags - } - return playParse(playObj); -} - -/** - * js源搜索返回的数据列表特定返回对象中的函数 - * @param wd 搜索关键字 - * @param quick 是否来自快速搜索 - * @returns {string} - */ -function search(wd, quick) { - let searchObj = { - searchUrl: rule.searchUrl, - 搜索: rule.搜索, - wd: wd, - //pg: pg, - pg: 1, - quick: quick, - }; - // console.log(JSON.stringify(searchObj)); - return searchParse(searchObj) -} - -function DRPY(){//导出函数 - return { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - } -} - -// 导出函数对象 -export default { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - DRPY:DRPY -} \ No newline at end of file diff --git a/lib/drpy2.js b/lib/drpy2.js deleted file mode 100644 index 81f5c112..00000000 --- a/lib/drpy2.js +++ /dev/null @@ -1,2246 +0,0 @@ -import cheerio from 'assets://js/lib/cheerio.min.js'; -import 'assets://js/lib/crypto-js.js'; -import 模板 from"../js/模板.js" -import {gbkTool} from './gbk.js' - -// import cheerio from "https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/cheerio.min.js"; -// import "https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-js.js"; -// import 模板 from"https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js"; -// import {gbkTool} from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/gbk.js' - -function init_test(){ - // console.log(typeof(CryptoJS)); - console.log("init_test_start"); - // print(模板); - // print(typeof(模板.getMubans)); - console.log("当前版本号:"+VERSION); - console.log(RKEY); - console.log(JSON.stringify(rule)); - console.log("init_test_end"); -} - -/** - * 执行预处理代码 - */ -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 { - // code里可以进行get 或者 post请求cookie并改变rule.headers 里的cookie - // 直接操作 rule_fetch_params 这个变量 .headers.Cookie - eval(code); - }catch (e) { - console.log('预处理执行失败:'+e.message); - } - } -} - -let rule = {}; -let vercode = typeof(pdfl) ==='function'?'drpy2.1':'drpy2'; -const VERSION = vercode+' 3.9.43beta1 20230607'; -/** 已知问题记录 - * 1.影魔的jinjia2引擎不支持 {{fl}}对象直接渲染 (有能力解决的话尽量解决下,支持对象直接渲染字符串转义,如果加了|safe就不转义)[影魔牛逼,最新的文件发现这问题已经解决了] - * Array.prototype.append = Array.prototype.push; 这种js执行后有毛病,for in 循环列表会把属性给打印出来 (这个大毛病需要重点排除一下) - * 2.import es6py.js但是里面的函数没有被装载进来.比如drpy规则报错setResult2 is undefiend(合并文件了可以不管了) - * 3.无法重复导入cheerio(怎么解决drpy和parseTag里都需要导入cheerio的问题) 无法在副文件导入cheerio (现在是全部放在drpy一个文件里了,凑合解决?) - * 4.有个错误不知道哪儿来的 executeScript: com.quickjs.JSObject$Undefined cannot be cast to java.lang.String 在 点击选集播放打印init_test_end后面打印(貌似不影响使用) - * 5.需要实现 stringify 函数,比起JSON.stringify函数,它会原封不动保留中文不会编码unicode - * 6.base64Encode,base64Decode,md5函数还没有实现 (抄影魔代码实现了) - * 7.eval(getCryptoJS());还没有实现 (可以空实现了,以后遇到能忽略) - * done: jsp:{pdfa,pdfh,pd},json:{pdfa,pdfh,pd},jq:{pdfa,pdfh,pd} - * 8.req函数不支持传递字符串的data参数 {'content-type':'text/plain'} 类型数据,因此无法直接调用alist的ocr接口 - * * 电脑看日志调试 - adb tcpip 5555 - adb connect 192.168.10.192 - adb devices -l - adb logcat -c - adb logcat | grep -i QuickJS - adb logcat -c -b events - adb logcat -c -b main -b events -b radio -b system - adb logcat > 2.log DRPY:E | grep -i QuickJS - * **/ - - -/*** 以下是内置变量和解析方法 **/ -const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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'; // 源cookie的key值 -// const KEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); // 源的唯一标识 -const CATE_EXCLUDE = '首页|留言|APP|下载|资讯|新闻|动态'; -const TAB_EXCLUDE = '猜你|喜欢|下载|剧情|热播'; -const OCR_RETRY = 3;//ocr验证重试次数 -// const OCR_API = 'http://dm.mudery.com:10000';//ocr在线识别接口 -// const OCR_API = 'http://192.168.3.239:5705/parse/ocr';//ocr在线识别接口 -// const OCR_API = 'http://cms.nokia.press/parse/ocr';//ocr在线识别接口 -// const OCR_API = 'http://cms.nokia.press:5707/parse/ocr';//ocr在线识别接口 -const OCR_API = 'http://drpy.nokia.press:8028/ocr/drpy/text';//ocr在线识别接口 -if(typeof(MY_URL)==='undefined'){ - var MY_URL; // 全局注入变量,pd函数需要 -} -var HOST; -var RKEY; // 源的唯一标识 -var fetch; -var print; -var log; -var rule_fetch_params; -var fetch_params; // 每个位置单独的 -var oheaders; -// var play_url; // 二级详情页注入变量,为了适配js模式0 (不在这里定义了,直接二级里定义了个空字符串) -var _pdfh; -var _pdfa; -var _pd; -// const DOM_CHECK_ATTR = ['url', 'src', 'href', 'data-original', 'data-src']; -const DOM_CHECK_ATTR = /(url|src|href|-original|-src|-play|-url)$/; -const NOADD_INDEX = /:eq|:lt|:gt|:first|:last|^body$|^#/; // 不自动加eq下标索引 -const URLJOIN_ATTR = /(url|src|href|-original|-src|-play|-url)$/; // 需要自动urljoin的属性 -const SELECT_REGEX = /:eq|:lt|:gt|#/g; -const SELECT_REGEX_A = /:eq|:lt|:gt/g; - -/** - es6py扩展 - */ -if (typeof Object.assign != 'function') { - Object.assign = function () { - var target = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; - }; -} -if (!String.prototype.includes) { - String.prototype.includes = function (search, start) { - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > this.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) {//this是空或者未定义,抛出错误 - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this);//将this转变成对象 - var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0 - - if (len === 0) {//length为0直接返回false未找到目标值 - return false; - } - - var n = fromIndex | 0;//查找起始索引 - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);//计算正确起始索引,因为有可能是负值 - - while (k < len) {//从起始索引处开始循环 - if (o[k] === searchElement) {//如果某一位置与寻找目标相等,返回true,找到了 - return true; - } - k++; - } - return false;//未找到,返回false - } - }); -} -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (prefix){ - return this.slice(0, prefix.length) === prefix; - }; -} -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function(suffix) { - return this.indexOf(suffix, this.length - suffix.length) !== -1; - }; -} -Object.prototype.myValues=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; -} -if (typeof Object.prototype.values != 'function') { - Object.prototype.values=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; - } -} -if (typeof Array.prototype.join != 'function') { - Array.prototype.join = function (emoji) { - // emoji = emoji||','; - emoji = emoji||''; - let self = this; - let str = ""; - let i = 0; - if (!Array.isArray(self)) {throw String(self)+'is not Array'} - if(self.length===0){return ''} - if (self.length === 1){return String(self[0])} - i = 1; - str = this[0]; - for (; i < self.length; i++) { - str += String(emoji)+String(self[i]); - } - return str; - }; -} - -String.prototype.rstrip = function (chars) { - let regex = new RegExp(chars + "$"); - return this.replace(regex, ""); -}; - -Array.prototype.append = Array.prototype.push; -String.prototype.strip = String.prototype.trim; -function 是否正版(vipUrl){ - let flag = new RegExp('qq\.com|iqiyi\.com|youku\.com|mgtv\.com|bilibili\.com|sohu\.com|ixigua\.com|pptv\.com|miguvideo\.com|le\.com|1905\.com|fun\.tv'); - return flag.test(vipUrl); -} -function urlDeal(vipUrl){ - if(!vipUrl){ - return '' - } - if(!是否正版(vipUrl)){ - return vipUrl - } - if(!/miguvideo/.test(vipUrl)){ - vipUrl=vipUrl.split('#')[0].split('?')[0]; - } - return vipUrl -} -function setResult(d){ - if(!Array.isArray(d)){ - return [] - } - VODS = []; - // print(d); - d.forEach(function (it){ - let obj = { - vod_id:it.url||'', - vod_name: it.title||'', - vod_remarks: it.desc||'', - vod_content: it.content||'', - vod_pic: it.pic_url||it.img||'', - }; - let keys = Object.keys(it); - if(keys.includes('tname')){ - obj.type_name = it.tname||''; - } - if(keys.includes('tid')){ - obj.type_id = it.tid||''; - } - if(keys.includes('year')){ - obj.vod_year = it.year||''; - } - if(keys.includes('actor')){ - obj.vod_actor = it.actor||''; - } - if(keys.includes('director')){ - obj.vod_director = it.director||''; - } - if(keys.includes('area')){ - obj.vod_area = it.area||''; - } - VODS.push(obj); - }); - return VODS -} -function setResult2(res){ - VODS = res.list||[]; - return VODS -} -function setHomeResult(res){ - if(!res||typeof(res)!=='object'){ - return [] - } - return setResult(res.list); -} -// 猫了个咪 -function rc(js) { - if (js === 'maomi_aes.js') { - var a = CryptoJS.enc.Utf8.parse("625222f9149e961d"); - var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330"); - return { - De: function (word) { - word = CryptoJS.enc.Hex.parse(word) - return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - }, - En: function (word) { - // print(a); - // print(word); - var Encrypted = CryptoJS.AES.encrypt(word, a, { - iv: t, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return Encrypted.ciphertext.toString(); - } - }; - } - return {}; -} - -// 千万不要用for in 推荐 forEach (for in 会打乱顺序) -//猫函数 -function maoss(jxurl, ref, key) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - eval(getCryptoJS()); - try { - var getVideoInfo = function (text) { - return CryptoJS.AES.decrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); - }; - var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key; - if (ref) { - var html = request(jxurl, { - headers: { - 'Referer': ref - } - }); - } else { - var html = request(jxurl); - } - // print(html); - if (html.indexOf('&btwaf=') != -1) { - html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], { - headers: { - 'Referer': ref - } - }) - } - var token_iv = html.split('_token = "')[1].split('"')[0]; - var key = CryptoJS.enc.Utf8.parse(token_key); - var iv = CryptoJS.enc.Utf8.parse(token_iv); - // log("iv:"+iv); - // log(html); - // print(key); - // print(iv); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - // config.url = config.url.replace(/,/g,''); - // print(config.url); - if (!config.url.startsWith('http')) { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - config.url = CryptoJS.AES.decrypt(config.url, key, { - iv: iv, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - } - return config.url; - } catch (e) { - return ''; - } -} - -function urlencode (str) { - str = (str + '').toString(); - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28'). - replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); -} - -function base64Encode(text){ - return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)); - // return text -} - -function base64Decode(text){ - return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text)); - // return text -} - -function md5(text) { - return CryptoJS.MD5(text).toString(); -} - -/** - * 字符串按指定编码 - * @param input - * @param encoding - * @returns {*} - */ -function encodeStr(input,encoding){ - encoding = encoding||'gbk'; - if(encoding.startsWith('gb')){ - const strTool = gbkTool(); - input = strTool.encode(input); - } - return input -} - -/** - * 字符串指定解码 - * @param input - * @param encoding - * @returns {*} - */ -function decodeStr(input,encoding){ - encoding = encoding||'gbk'; - if(encoding.startsWith('gb')){ - const strTool = gbkTool(); - input = strTool.decode(input); - } - return input -} - -function getCryptoJS(){ - // return request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-hiker.js'); - return 'console.log("CryptoJS已装载");' -} - -/** - * 强制正序算法 - * @param lists 待正序列表 - * @param key 正序键 - * @param option 单个元素处理函数 - * @returns {*} - */ -function forceOrder(lists,key,option){ - let start = Math.floor(lists.length/2); - let end = Math.min(lists.length-1,start+1); - if(start >= 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+=''; - // console.log(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 = [];// 二级的自定义线路列表 如: TABS=['道长在线','道长在线2'] -let LISTS = [];// 二级的自定义选集播放列表 如: LISTS=[['第1集$http://1.mp4','第2集$http://2.mp4'],['第3集$http://1.mp4','第4集$http://2.mp4']] -globalThis.encodeUrl = urlencode; -globalThis.urlencode = urlencode; - - - -/** - * url拼接 - * @param fromPath 初始当前页面url - * @param nowPath 相对当前页面url - * @returns {*} - */ -function urljoin(fromPath, nowPath) { - fromPath = fromPath||''; - nowPath = nowPath||''; - return joinUrl(fromPath, nowPath); - // try { - // // import Uri from './uri.min.js'; - // // var Uri = require('./uri.min.js'); - // // eval(request('https://cdn.bootcdn.net/ajax/libs/URI.js/1.19.11/URI.min.js')); - // // let new_uri = URI(nowPath, fromPath); - - // let new_uri = Uri(nowPath, fromPath); - // new_uri = new_uri.toString(); - // // console.log(new_uri); - // // return fromPath + nowPath - // return new_uri - // } - // catch (e) { - // console.log('urljoin发生错误:'+e.message); - // if(nowPath.startsWith('http')){ - // return nowPath - // }if(nowPath.startsWith('/')){ - // return getHome(fromPath)+nowPath - // } - // return fromPath+nowPath - // } -} -var urljoin2 = urljoin; - -// 内置 pdfh,pdfa,pd -const defaultParser = { - pdfh:pdfh, - pdfa:pdfa, - pd:pd, -}; - - -/** - * pdfh原版优化,能取style属性里的图片链接 - * @param html 源码 - * @param parse 解析表达式 - * @returns {string|*} - */ -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]; - }catch (e) {} - } - return result -} - -/** - * pdfa原版优化,可以转换jq的html对象 - * @param html - * @param parse - * @returns {*} - */ -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); -} - -/** - * pd原版方法重写-增加自动urljoin - * @param html - * @param parse - * @param uri - * @returns {*} - */ -function pd2(html,parse,uri){ - let ret = pdfh2(html,parse); - if(typeof(uri)==='undefined'||!uri){ - uri = ''; - } - if(DOM_CHECK_ATTR.test(parse)){ - if(/http/.test(ret)){ - ret = ret.substr(ret.indexOf('http')); - }else{ - ret = urljoin(MY_URL,ret) - } - } - // MY_URL = getItem('MY_URL',MY_URL); - // console.log(`规则${RKEY}打印MY_URL:${MY_URL},uri:${uri}`); - return ret -} - -const parseTags = { - jsp:{ - pdfh:pdfh2, - pdfa:pdfa2, - pd:pd2, - }, - json:{ - pdfh(html, parse) { - if (!parse || !parse.trim()){ - return ''; - } - if (typeof(html) === 'string'){ - // print('jsonpath:pdfh字符串转dict'); - 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'){ - // print('jsonpath:pdfa字符串转dict'); - 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); - // print(`pdfh解析${parse}=>${result}`); - return result; - }, - pdfa(html, parse) { - if (!html||!parse || !parse.trim()) { - return []; - } - parse = parse.trim(); - let result = defaultParser.pdfa(html,parse); - // print(result); - 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){//非js开头的情况自动获取解析标签 - 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; - -/*** 后台需要实现的java方法并注入到js中 ***/ - -/** - * 读取本地文件->应用程序目录 - * @param filePath - * @returns {string} - */ -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 -} - -/** - * 处理返回的json数据 - * @param html - * @returns {*} - */ -function dealJson(html) { - try { - // html = html.match(/[\w|\W|\s|\S]*?(\{[\w|\W|\s|\S]*\})/).group[1]; - 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) {} - // console.log(typeof(html)); - return html; -} - -/** - * 验证码识别逻辑,需要java实现(js没有bytes类型,无法调用后端的传递图片二进制获取验证码文本的接口) - * @type {{api: string, classification: (function(*=): string)}} - */ -var OcrApi={ - api:OCR_API, - classification:function (img){ // img是byte类型,这里不方便搞啊 - let code = ''; - try { - // let html = request(this.api,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true); - // html = JSON.parse(html); - // code = html.url||''; - log('通过drpy_ocr验证码接口过验证...'); - let html = request(OCR_API,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true); - code = html||''; - }catch (e) { - log(`OCR识别验证码发生错误:${e.message}`) - } - return code - } -}; -/** - * 验证码识别,暂未实现 - * @param url 验证码图片链接 - * @returns {string} 验证成功后的cookie - */ -function verifyCode(url){ - let cnt = 0; - let host = getHome(url); - let cookie = ''; - while (cnt < OCR_RETRY){ - try{ - // let obj = {headers:headers,timeout:timeout}; - let yzm_url = `${host}/index.php/verify/index.html`; - console.log(`验证码链接:${yzm_url}`); - let hhtml = request(yzm_url,{withHeaders:true,toBase64:true},true); - let json = JSON.parse(hhtml); - if(!cookie){ - // print(json); - let setCk = Object.keys(json).find(it=>it.toLowerCase()==='set-cookie'); - // cookie = json['set-cookie']?json['set-cookie'].split(';')[0]:''; - cookie = setCk?json[setCk].split(';')[0]:''; - } - // console.log(hhtml); - console.log('cookie:'+cookie); - let img = json.body; - // console.log(img); - 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,'User-Agent':MOBILE_UA},'method':'POST'}); - // console.log(html); - html = JSON.parse(html); - if(html.msg === 'ok'){ - console.log(`第${cnt+1}次验证码提交成功`); - return cookie // 需要返回cookie - }else if(html.msg!=='ok'&&cnt+1>=OCR_RETRY){ - cookie = ''; // 需要清空返回cookie - } - }catch (e) { - console.log(`第${cnt+1}次验证码提交失败:${e.message}`); - if(cnt+1>=OCR_RETRY){ - cookie = ''; - } - } - cnt+=1 - } - return cookie -} - -/** - * 存在数据库配置表里, key字段对应值value,没有就新增,有就更新,调用此方法会清除key对应的内存缓存 - * @param k 键 - * @param v 值 - */ -function setItem(k,v){ - local.set(RKEY,k,v); - console.log(`规则${RKEY}设置${k} => ${v}`) -} - -/** - * 获取数据库配置表对应的key字段的value,没有这个key就返回value默认传参.需要有缓存,第一次获取后会存在内存里 - * @param k 键 - * @param v 值 - * @returns {*} - */ -function getItem(k,v){ - return local.get(RKEY,k) || v; -} - -/** - * 删除数据库key对应的一条数据,并清除此key对应的内存缓存 - * @param k - */ -function clearItem(k){ - local.delete(RKEY,k); -} - -/*** js自封装的方法 ***/ - -/** - * 获取链接的host(带http协议的完整链接) - * @param url 任意一个正常完整的Url,自动提取根 - * @returns {string} - */ -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 -} - -/** - * get参数编译链接,类似python params字典自动拼接 - * @param url 访问链接 - * @param obj 参数字典 - * @returns {*} - */ -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 -} - -/** - * 远程依赖执行函数 - * @param url 远程js地址 - */ -function require(url){ - eval(request(url)); -} -/** - * 海阔网页请求函数完整封装 - * @param url 请求链接 - * @param obj 请求对象 {headers:{},method:'',timeout:5000,body:'',withHeaders:false} - * @param ocr_flag 标识此flag是用于请求ocr识别的,自动过滤content-type指定编码 - * @returns {string|string|DocumentFragment|*} - */ -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(!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'){ - // let data = {}; - // obj.body.split('&').forEach(it=>{ - // data[it.split('=')[0]] = it.split('=')[1] - // }); - // obj.data = data; - // delete obj.body - - // 传body加 "Content-Type":"application/x-www-form-urlencoded;" 即可post form - 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){ // 返回base64,用于请求图片 - obj.buffer = 2; - delete obj.toBase64 - } - console.log(JSON.stringify(obj.headers)); - // console.log('request:'+url+' obj:'+JSON.stringify(obj)); - console.log('request:'+url+`|method:${obj.method||'GET'}|body:${obj.body||''}`); - let res = req(url, obj); - let html = res.content||''; - // console.log(html); - if(obj.withHeaders){ - let htmlWithHeaders = res.headers; - htmlWithHeaders.body = html; - return JSON.stringify(htmlWithHeaders); - }else{ - return html - } -} - -/** - * 快捷post请求 - * @param url 地址 - * @param obj 对象 - * @returns {string|DocumentFragment|*} - */ -function post(url,obj){ - obj.method = 'POST'; - return request(url,obj); -} - -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('print:'+e.message); - 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; -/** - * 检查宝塔验证并自动跳过获取正确源码 - * @param html 之前获取的html - * @param url 之前的来源url - * @param obj 来源obj - * @returns {string|DocumentFragment|*} - */ -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 -} - -/** - * 带一次宝塔验证的源码获取 - * @param url 请求链接 - * @param obj 请求参数 - * @returns {string|DocumentFragment} - */ -function getCode(url,obj){ - let html = request(url,obj); - html = checkHtml(html,url,obj); - return html -} - -/** - * 源rule专用的请求方法,自动注入cookie - * @param url 请求链接 - * @returns {string|DocumentFragment} - */ -function getHtml(url){ - let obj = {}; - if(rule.headers){ - obj.headers = rule.headers; - } - let cookie = getItem(RULE_CK,''); - if(cookie){ - // log('有cookie:'+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 -} - -/** - * 首页分类解析,筛选暂未实现 - * @param homeObj 首页传参对象 - * @returns {string} - */ -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; i < cnt; i++) { - classes.push({ - 'type_id': urls[i], - 'type_name': names[i] - }); - } - } - - if (homeObj.class_parse) { - let p = homeObj.class_parse.split(';'); - let _ps = parseTags.getParse(p[0]); - _pdfa = _ps.pdfa; - _pdfh = _ps.pdfh; - _pd = _ps.pd; - MY_URL = rule.url; - if (p.length >= 3) { // 可以不写正则 - try { - let html = getHtml(homeObj.MY_URL); - if (html) { - homeHtmlCache = html; - let list = _pdfa(html, p[0]); - 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 = pdfh(it, p[2]); - let url = _pd(it, p[2]); - if (p.length > 3 && p[3]) { - 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); - -} - -/** - * 推荐和搜索单字段继承一级 - * @param p 推荐或搜索的解析分割;列表 - * @param pn 自身列表序号 - * @param pp 一级解析分割;列表 - * @param ppn 继承一级序号 - * @returns {*} - */ -function getPP(p, pn, pp, ppn){ - try { - let ps = p[pn] === '*' && pp.length > ppn ?pp[ppn]:p[pn] - return ps - }catch (e) { - return '' - } -} - -/** - * 首页推荐列表解析 - * @param homeVodObj - * @returns {string} - */ -function homeVodParse(homeVodObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - MY_URL = homeVodObj.homeUrl; - // setItem('MY_URL',MY_URL); - 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.一级.split(';'); - if(p.startsWith('js:')){ - const TYPE = 'home'; - var input = MY_URL; - const 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:)/,''); - // print(p[0]); - let html = homeHtmlCache || getHtml(MY_URL); - homeHtmlCache = undefined; - if(is_json){ - // print('是json,开始处理'); - html = dealJson(html); - } - try { - console.log('double:' + homeVodObj.double); - if (homeVodObj.double) { - let items = _pdfa(html, p0); - // console.log(items.length); - 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) { - // console.log(p[1]); - let items2 = _pdfa(item, p1); - // console.log(items2.length); - 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 - }; - // print(vod); - 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)+'毫秒'); - // console.log(JSON.stringify(d)); - 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 - }) -} - -/** - * 一级分类页数据解析 - * @param cateObj - * @returns {string} - */ -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).replaceAll('fypage', cateObj.pg); - 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); - } - // console.log('filter:'+cateObj.filter); - 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'){ - // 引用传递转值传递,避免污染self变量 - 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}); - // console.log('jinjia2执行后的new_url类型为:'+typeof(new_url)); - url = new_url; - } - if(/fypage/.test(url)){ - if(url.includes('(')&&url.includes(')')){ - let url_rep = url.match(/.*?\((.*)\)/)[1]; - // console.log(url_rep); - let cnt_page = url_rep.replaceAll('fypage', cateObj.pg); - // console.log(cnt_page); - let cnt_pg = eval(cnt_page); - // console.log(cnt_pg); - url = url.replaceAll(url_rep,cnt_pg).replaceAll('(','').replaceAll(')',''); - }else{ - url = url.replaceAll('fypage',cateObj.pg); - } - } - - MY_URL = url; - // setItem('MY_URL',MY_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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - 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, - }); - // print(vod); - return vod -} - -/** - * 搜索列表数据解析 - * @param searchObj - * @returns {string} - */ -function searchParse(searchObj) { - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - let d = []; - if(!searchObj.searchUrl){ - return '{}' - } - let p = searchObj.搜索==='*'&&rule.一级 ? rule.一级 : searchObj.搜索; - if(!p||typeof(p)!=='string'){ - return '{}' - } - p = p.trim(); - let pp = rule.一级.split(';'); - let url = searchObj.searchUrl.replaceAll('**', searchObj.wd).replaceAll('fypage', searchObj.pg); - MY_URL = url; - console.log(MY_URL); - // log(searchObj.搜索); - // setItem('MY_URL',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:)/,''); - // print('1381 p0:'+p0); - 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 new_dict = {}; - // let new_tmp = params.split('&'); - // new_tmp.forEach(i=>{ - // new_dict[i.split('=')[0]] = i.split('=')[1]; - // }); - // html = post(rurl,{body:new_dict}); - 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) { - if(/系统安全验证|输入验证码/.test(html)){ - let cookie = verifyCode(MY_URL); - if(cookie){ - console.log(`本次成功过验证,cookie:${cookie}`); - setItem(RULE_CK,cookie); - }else{ - console.log(`本次自动过搜索验证失败,cookie:${cookie}`); - } - // obj.headers['Cookie'] = cookie; - html = getHtml(MY_URL); - } - if(!html.includes(searchObj.wd)){ - console.log('搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码'); - console.log(html); - } - if(is_json){ - // console.log(html); - html = dealJson(html); - // console.log(JSON.stringify(html)); - } - // console.log(html); - let list = _pdfa(html, p0); - // print(list.length); - // print(list); - 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.图片来源){ - d.forEach(it=>{ - if(it.vod_pic&&it.vod_pic.startsWith('http')){ - it.vod_pic = it.vod_pic + rule.图片来源; - } - }); - } - // print(d); - return JSON.stringify({ - 'page': parseInt(searchObj.pg), - 'pagecount': 10, - 'limit': 20, - 'total': 100, - 'list': d, - }); -} - -/** - * 二级详情页数据解析 - * @param detailObj - * @returns {string} - */ -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.二级==='*'){ - // vod_id = orId.split('@@')[0]; // 千万不能分割 - let extra = orId.split('@@'); - vod_name = extra.length>1?extra[1]:vod_name; - vod_pic = extra.length>2?extra[2]:vod_pic; - } - // print(vod_pic); - let vod = { - vod_id: vod_id, //"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}`) - } - } - // console.log(MY_URL); - // setItem('MY_URL',MY_URL); - 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; - // print('二级默认jsp'); - // _ps = parseTags.jsp; - } - 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]).replaceAll('\n', ' ').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:','')); - } - -// console.log(2); - 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]; - // console.log(p_tab); - let vHeader = _pdfa(html, p_tab); - console.log(vHeader.length); - let tab_text = p.tab_text||'body&&Text'; - // print('tab_text:'+tab_text); - let new_map = {}; - for(let v of vHeader){ - let v_title = _pdfh(v,tab_text).trim(); - 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); - -// console.log(3); - 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)){ - // print(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'; - // print('list_text:'+list_text); - // print('list_url:'+list_url); - // print('list_parse:'+p.lists); - let is_tab_js = p.tabs.trim().startsWith('js:'); - for(let i=0;i 1 && !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); - // print('tab_ext:'+tab_ext); - let new_vod_list = []; - let tt1 = (new Date()).getTime(); - // print('pdfl:'+typeof (pdfl)); - if(typeof (pdfl) ==='function'){ - new_vod_list = pdfl(html, p1, list_text, list_url, MY_URL); - }else { - let vodList = []; - try { - vodList = _pdfa(html, p1); - console.log('len(vodList):'+vodList.length); - }catch (e) { - // console.log(e.message); - } - for (let i = 0; i < vodList.length; i++) { - let it = vodList[i]; - new_vod_list.push(_pdfh(it, list_text).trim() + '$' + _pd(it, list_url, MY_URL)); - } - } - if(new_vod_list.length>0){ - new_vod_list = forceOrder(new_vod_list,'',x=>x.split('$')[0]); - console.log(`drpy影响性能代码共计列表数循环次数:${new_vod_list.length},耗时:${(new Date()).getTime()-tt1}毫秒`); - } - // print(new_vod_list); - 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.图片来源 && 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}毫秒`); - // print(vod); - return JSON.stringify({ - list: [vod] - }) -} - -/** - * 判断是否需要解析 - * @param url - * @returns {number|number} - */ -function tellIsJx(url){ - try { - let is_vip = !/\.(m3u8|mp4|m4a)$/.test(url.split('?')[0]) && 是否正版(url); - return is_vip?1:0 - }catch (e) { - return 1 - } -} -/** - * 选集播放点击事件解析 - * @param playObj - * @returns {string} - */ -function playParse(playObj){ - fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); - MY_URL = playObj.url; - if(!/http/.test(MY_URL)){ - try { - MY_URL = base64Decode(MY_URL); - }catch (e) {} - } - MY_URL = decodeURIComponent(MY_URL); - var input = MY_URL;//注入给免嗅js - let common_play = { - parse:1, - url:input, - // url:urlencode(input), - 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.replace('js:','').trim(); - print('开始执行js免嗅=>'+lazy_code); - eval(lazy_code); - lazy_play = typeof(input) === 'object'?input:{ - parse:1, - jx:tellIsJx(input), - url:input - }; - }catch (e) { - print('js免嗅错误:'+e.message); - lazy_play = common_play; - } - }else{ - lazy_play = common_play; - } - // print('play_json:'+typeof(rule.play_json)); - // console.log(Array.isArray(rule.play_json)); - if(Array.isArray(rule.play_json) && rule.play_json.length >0){ // 数组情况判断长度大于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; - // print('开始合并:'); - // print(base_json); - lazy_play = Object.assign(lazy_play,base_json); - break; - } - } - } - }else if(rule.play_json && !Array.isArray(rule.play_json)){ // 其他情况 非[] 判断true/false - let base_json = { - jx:1, - parse:1, - }; - lazy_play = Object.assign(lazy_play,base_json); - }else if(!rule.play_json){ // 不解析传0 - 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); -} - -/** - * js源预处理特定返回对象中的函数 - * @param ext - */ -function init(ext) { - console.log('init'); - try { - // make shared jsContext happy muban不能import,不然会造成换源继承后变量被篡改 - // if (typeof (globalThis.mubanJs) === 'undefined') { - // let mubanJs = request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js', { 'User-Agent': MOBILE_UA }); - // mubanJs = mubanJs.replace('export default', '(function() {return muban;}()) // export default'); - // // console.log(mubanJs); - // globalThis.mubanJs = mubanJs; - // } - // let muban = eval(globalThis.mubanJs); - - let muban = 模板.getMubans(); - // print(typeof (muban)); - // print(muban); - if (typeof ext == 'object'){ - rule = ext; - } else if (typeof ext == 'string') { - if (ext.startsWith('http')) { - let js = request(ext,{'method':'GET'}); - if (js){ - eval(js.replace('var rule', 'rule')); - } - } else { - eval(ext.replace('var rule', 'rule')); - } - } - if (rule.模板 && muban.hasOwnProperty(rule.模板)) { - print('继承模板:'+rule.模板); - rule = Object.assign(muban[rule.模板], 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.host = (rule.host||'').rstrip('/'); - HOST = rule.host; - if(rule.hostJs){ - try { - eval(rule.hostJs); - rule.host = HOST.rstrip('/'); - }catch (e) { - console.log(`执行${rule.hostJs}获取host发生错误:`+e.message); - } - } - 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.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; - } - rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host,rule.searchUrl) : rule.searchUrl; - - rule.timeout = rule.timeout||5000; - rule.encoding = rule.编码||rule.encoding||'utf-8'; - rule.search_encoding = rule.搜索编码||rule.search_encoding||''; - rule.图片来源 = rule.图片来源||''; - rule.play_json = rule.hasOwnProperty('play_json')?rule.play_json:[]; - rule.pagecount = rule.hasOwnProperty('pagecount')?rule.pagecount:{}; - 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); - } - } - // print(rule.headers); - rule_fetch_params = {'headers': rule.headers||false, 'timeout': rule.timeout, 'encoding': rule.encoding}; - oheaders = rule.headers||{}; - RKEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); - pre(); // 预处理 - init_test(); - }catch (e) { - console.log('init_test发生错误:'+e.message); - } -} - -let homeHtmlCache = undefined; - -/** - * js源获取首页分类和筛选特定返回对象中的函数 - * @param filter 筛选条件字典对象 - * @returns {string} - */ -function home(filter) { - console.log("home"); - let homeObj = { - filter:rule.filter||false, - MY_URL: rule.homeUrl, - class_name: rule.class_name || '', - class_url: rule.class_url || '', - class_parse: rule.class_parse || '', - cate_exclude: rule.cate_exclude, - }; - return homeParse(homeObj); -} - -/** - * js源获取首页推荐数据列表特定返回对象中的函数 - * @param params - * @returns {string} - */ -function homeVod(params) { - console.log("homeVod"); - let homeVodObj = { - 推荐:rule.推荐, - double:rule.double, - homeUrl:rule.homeUrl, - detailUrl:rule.detailUrl - }; - return homeVodParse(homeVodObj) - // return "{}"; -} - -/** - * js源获取分类页一级数据列表特定返回对象中的函数 - * @param tid 分类id - * @param pg 页数 - * @param filter 当前选中的筛选条件 - * @param extend 扩展 - * @returns {string} - */ -function category(tid, pg, filter, extend) { - let cateObj = { - url: rule.url, - 一级: rule.一级, - tid: tid, - pg: parseInt(pg), - filter: filter, - extend: extend - }; - // console.log(JSON.stringify(extend)); - return categoryParse(cateObj) -} - -/** - * js源获取二级详情页数据特定返回对象中的函数 - * @param vod_url 一级列表中的vod_id或者是带分类的自拼接 vod_id 如 fyclass$vod_id - * @returns {string} - */ -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) -} - -/** - * js源选集按钮播放点击事件特定返回对象中的函数 - * @param flag 线路名 - * @param id 播放按钮的链接 - * @param flags 全局配置的flags是否需要解析的标识列表 - * @returns {string} - */ -function play(flag, id, flags) { - let playObj = { - url:id, - flag:flag, - flags:flags - } - return playParse(playObj); -} - -/** - * js源搜索返回的数据列表特定返回对象中的函数 - * @param wd 搜索关键字 - * @param quick 是否来自快速搜索 - * @returns {string} - */ -function search(wd, quick) { - 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, - pg: 1, - quick: quick, - }; - // console.log(JSON.stringify(searchObj)); - return searchParse(searchObj) -} - -function DRPY(){//导出函数 - return { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - } -} - -// 导出函数对象 -export default { - init: init, - home: home, - homeVod: homeVod, - category: category, - detail: detail, - play: play, - search: search, - DRPY:DRPY -} \ No newline at end of file diff --git a/lib/drpy2.min.js b/lib/drpy2.min.js deleted file mode 100644 index c4d06cb7..00000000 --- a/lib/drpy2.min.js +++ /dev/null @@ -1 +0,0 @@ -import cheerio from"assets://js/lib/cheerio.min.js";import"assets://js/lib/crypto-js.js";import 模板 from"./模板.js";import{gbkTool}from"./gbk.js";function init_test(){console.log("init_test_start");console.log("当前版本号:"+VERSION);console.log(RKEY);console.log(JSON.stringify(rule));console.log("init_test_end")}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={};let vercode=typeof pdfl==="function"?"drpy2.1":"drpy2";const VERSION=vercode+" 3.9.41beta14 20230428";const MOBILE_UA="Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 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="http://drpy.nokia.press:8028/ocr/drpy/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)$/;const NOADD_INDEX=/:eq|:lt|:gt|:first|:last|^body$|^#/;const URLJOIN_ATTR=/(url|src|href|-original|-src|-play|-url)$/;const SELECT_REGEX=/:eq|:lt|:gt|#/g;const SELECT_REGEX_A=/:eq|:lt|:gt/g;if(typeof Object.assign!="function"){Object.assign=function(){var target=arguments[0];for(var i=1;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=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=[];globalThis.encodeUrl=urlencode;globalThis.urlencode=urlencode;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]}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)){if(/http/.test(ret)){ret=ret.substr(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=request(OCR_API,{data:{img:img},headers:{"User-Agent":PC_UA},method:"POST"},true);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,"User-Agent":MOBILE_UA},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 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(!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}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.method="POST";return request(url,obj)}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;i=3){try{let html=getHtml(homeObj.MY_URL);if(html){homeHtmlCache=html;let list=_pdfa(html,p[0]);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]){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.一级.split(";");if(p.startsWith("js:")){const TYPE="home";var input=MY_URL;const 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.图片来源){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)}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});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.图片来源){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"{}"}let p=searchObj.搜索==="*"&&rule.一级?rule.一级:searchObj.搜索;if(!p||typeof p!=="string"){return"{}"}p=p.trim();let pp=rule.一级.split(";");let url=searchObj.searchUrl.replaceAll("**",searchObj.wd).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){if(/系统安全验证|输入验证码/.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.图片来源){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();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 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)}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.图片来源&&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}毫秒`);return JSON.stringify({list:[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;if(!/http/.test(MY_URL)){try{MY_URL=base64Decode(MY_URL)}catch(e){}}MY_URL=decodeURIComponent(MY_URL);var input=MY_URL;let common_play={parse:1,url:input,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.replace("js:","").trim();print("开始执行js免嗅=>"+lazy_code);eval(lazy_code);lazy_play=typeof input==="object"?input:{parse: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 init(ext){console.log("init");try{let muban=模板.getMubans();if(typeof ext=="object"){rule=ext}else if(typeof ext=="string"){if(ext.startsWith("http")){let js=request(ext,{method:"GET"});if(js){eval(js.replace("var rule","rule"))}}else{eval(ext.replace("var rule","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.host=(rule.host||"").rstrip("/");HOST=rule.host;if(rule.hostJs){try{eval(rule.hostJs);rule.host=HOST.rstrip("/")}catch(e){console.log(`执行${rule.hostJs}获取host发生错误:`+e.message)}}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.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}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.play_json=rule.hasOwnProperty("play_json")?rule.play_json:[];rule.pagecount=rule.hasOwnProperty("pagecount")?rule.pagecount:{};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)}}rule_fetch_params={headers:rule.headers||false,timeout:rule.timeout,encoding:rule.encoding};oheaders=rule.headers||{};RKEY=typeof key!=="undefined"&&key?key:"drpy_"+(rule.title||rule.host);pre();init_test()}catch(e){console.log("init_test发生错误:"+e.message)}}let homeHtmlCache=undefined;function home(filter){console.log("home");let homeObj={filter:rule.filter||false,MY_URL:rule.homeUrl,class_name:rule.class_name||"",class_url:rule.class_url||"",class_parse:rule.class_parse||"",cate_exclude:rule.cate_exclude};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){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:1,quick:quick};return searchParse(searchObj)}function DRPY(){return{init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search}}export default{init:init,home:home,homeVod:homeVod,category:category,detail:detail,play:play,search:search,DRPY:DRPY}; \ No newline at end of file diff --git a/lib/gbk.js b/lib/gbk.js deleted file mode 100644 index 796d53ac..00000000 --- a/lib/gbk.js +++ /dev/null @@ -1,68 +0,0 @@ -/*** - * gbk编码解码函数 - * strTool = gbkTool() strTool.encode(key) - * @returns {{encode: (function(*): *), decode: (function(*): *)}} - */ -export function gbkTool(){ - var data=function(zipData){ - var re=zipData - .replace(/#(\d+)\$/g,function(a,b){ - return Array(+b+3).join('#'); - }) - .replace(/#/g,'####') - .replace(/(\w\w):([\w#]+)(?:,|$)/g,function(a,hd,dt){ - return dt.replace(/../g,function(a){ - if(a!='##'){ - return hd+a; - }else{ - return a; - } - }); - }); - return re; - }('4e:020405060f12171f20212326292e2f313335373c40414244464a5155575a5b6263646567686a6b6c6d6e6f727475767778797a7b7c7d7f808182838485878a#909697999c9d9ea3aaafb0b1b4b6b7b8b9bcbdbec8cccfd0d2dadbdce0e2e6e7e9edeeeff1f4f8f9fafcfe,4f:00020304050607080b0c12131415161c1d212328292c2d2e31333537393b3e3f40414244454748494a4b4c525456616266686a6b6d6e7172757778797a7d8081828586878a8c8e909293959698999a9c9e9fa1a2a4abadb0b1b2b3b4b6b7b8b9babbbcbdbec0c1c2c6c7c8c9cbcccdd2d3d4d5d6d9dbe0e2e4e5e7ebecf0f2f4f5f6f7f9fbfcfdff,50:000102030405060708090a#0b0e1011131516171b1d1e20222324272b2f303132333435363738393b3d3f404142444546494a4b4d5051525354565758595b5d5e5f6061626364666768696a6b6d6e6f70717273747578797a7c7d818283848687898a8b8c8e8f909192939495969798999a9b9c9d9e9fa0a1a2a4a6aaabadaeafb0b1b3b4b5b6b7b8b9bcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdced0d1d2d3d4d5d7d8d9dbdcdddedfe0e1e2e3e4e5e8e9eaebeff0f1f2f4f6f7f8f9fafcfdfeff,51:00010203040508#090a0c0d0e0f1011131415161718191a1b1c1d1e1f2022232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e42474a4c4e4f5052535758595b5d5e5f606163646667696a6f727a7e7f838486878a8b8e8f90919394989a9d9e9fa1a3a6a7a8a9aaadaeb4b8b9babebfc1c2c3c5c8cacdced0d2d3d4d5d6d7d8d9dadcdedfe2e3e5e6e7e8e9eaeceef1f2f4f7fe,52:0405090b0c0f101314151c1e1f2122232526272a2c2f313234353c3e4445464748494b4e4f5253555758#595a5b5d5f6062636466686b6c6d6e7071737475767778797a7b7c7e808384858687898a8b8c8d8e8f91929495969798999a9ca4a5a6a7aeafb0b4b5b6b7b8b9babbbcbdc0c1c2c4c5c6c8cacccdcecfd1d3d4d5d7d9dadbdcdddee0e1e2e3e5e6e7e8e9eaebecedeeeff1f2f3f4f5f6f7f8fbfcfd,53:0102030407090a0b0c0e11121314181b1c1e1f2224252728292b2c2d2f3031323334353637383c3d404244464b4c4d505458595b5d65686a6c6d7276797b7c7d7e80818387888a8e8f#90919293949697999b9c9ea0a1a4a7aaabacadafb0b1b2b3b4b5b7b8b9babcbdbec0c3c4c5c6c7cecfd0d2d3d5dadcdddee1e2e7f4fafeff,54:000205070b1418191a1c2224252a303336373a3d3f4142444547494c4d4e4f515a5d5e5f6061636567696a6b6c6d6e6f7074797a7e7f8183858788898a8d919397989c9e9fa0a1a2a5aeb0b2b5b6b7b9babcbec3c5cacbd6d8dbe0e1e2e3e4ebeceff0f1f4f5f6f7f8f9fbfe,55:0002030405080a0b0c0d0e121315161718191a1c1d1e1f212526#28292b2d3234353638393a3b3d40424547484b4c4d4e4f515253545758595a5b5d5e5f60626368696b6f7071727374797a7d7f85868c8d8e9092939596979a9b9ea0a1a2a3a4a5a6a8a9aaabacadaeafb0b2b4b6b8babcbfc0c1c2c3c6c7c8cacbcecfd0d5d7d8d9dadbdee0e2e7e9edeef0f1f4f6f8f9fafbfcff,56:0203040506070a0b0d1011121314151617191a1c1d202122252628292a2b2e2f30333537383a3c3d3e404142434445464748494a4b4f5051525355565a5b5d5e5f6061#636566676d6e6f70727374757778797a7d7e7f80818283848788898a8b8c8d9091929495969798999a9b9c9d9e9fa0a1a2a4a5a6a7a8a9aaabacadaeb0b1b2b3b4b5b6b8b9babbbdbebfc0c1c2c3c4c5c6c7c8c9cbcccdcecfd0d1d2d3d5d6d8d9dce3e5e6e7e8e9eaeceeeff2f3f6f7f8fbfc,57:00010205070b0c0d0e0f101112131415161718191a1b1d1e202122242526272b313234353637383c3d3f414344454648494b52535455565859626365676c6e707172747578797a7d7e7f80#818788898a8d8e8f90919495969798999a9c9d9e9fa5a8aaacafb0b1b3b5b6b7b9babbbcbdbebfc0c1c4c5c6c7c8c9cacccdd0d1d3d6d7dbdcdee1e2e3e5e6e7e8e9eaebeceef0f1f2f3f5f6f7fbfcfeff,58:0103040508090a0c0e0f101213141617181a1b1c1d1f222325262728292b2c2d2e2f31323334363738393a3b3c3d3e3f4041424345464748494a4b4e4f505253555657595a5b5c5d5f6061626364666768696a6d6e6f707172737475767778797a7b7c7d7f82848687888a8b8c#8d8e8f909194959697989b9c9da0a1a2a3a4a5a6a7aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbdbebfc0c2c3c4c6c7c8c9cacbcccdcecfd0d2d3d4d6d7d8d9dadbdcdddedfe0e1e2e3e5e6e7e8e9eaedeff1f2f4f5f7f8fafbfcfdfeff,59:000103050608090a0b0c0e1011121317181b1d1e2021222326282c30323335363b3d3e3f404345464a4c4d505253595b5c5d5e5f616364666768696a6b6c6d6e6f70717275777a7b7c7e7f8085898b8c8e8f90919495989a9b9c9d9fa0a1a2a6#a7acadb0b1b3b4b5b6b7b8babcbdbfc0c1c2c3c4c5c7c8c9cccdcecfd5d6d9dbdedfe0e1e2e4e6e7e9eaebedeeeff0f1f2f3f4f5f6f7f8fafcfdfe,5a:00020a0b0d0e0f101214151617191a1b1d1e2122242627282a2b2c2d2e2f3033353738393a3b3d3e3f414243444547484b4c4d4e4f5051525354565758595b5c5d5e5f60616364656668696b6c6d6e6f7071727378797b7c7d7e808182838485868788898a8b8c8d8e8f9091939495969798999c9d9e9fa0a1a2a3a4a5a6a7a8a9abac#adaeafb0b1b4b6b7b9babbbcbdbfc0c3c4c5c6c7c8cacbcdcecfd0d1d3d5d7d9dadbdddedfe2e4e5e7e8eaecedeeeff0f2f3f4f5f6f7f8f9fafbfcfdfeff,5b:0001020304050607080a0b0c0d0e0f10111213141518191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303133353638393a3b3c3d3e3f4142434445464748494a4b4c4d4e4f52565e606167686b6d6e6f7274767778797b7c7e7f82868a8d8e90919294969fa7a8a9acadaeafb1b2b7babbbcc0c1c3c8c9cacbcdcecf#d1d4d5d6d7d8d9dadbdce0e2e3e6e7e9eaebecedeff1f2f3f4f5f6f7fdfe,5c:0002030507080b0c0d0e10121317191b1e1f2021232628292a2b2d2e2f303233353637434446474c4d5253545657585a5b5c5d5f62646768696a6b6c6d70727374757677787b7c7d7e808384858687898a8b8e8f9293959d9e9fa0a1a4a5a6a7a8aaaeafb0b2b4b6b9babbbcbec0c2c3c5c6c7c8c9cacccdcecfd0d1d3d4d5d6d7d8dadbdcdddedfe0e2e3e7e9ebeceeeff1f2f3f4f5f6f7f8f9fafcfdfeff,5d:00#01040508090a0b0c0d0f10111213151718191a1c1d1f2021222325282a2b2c2f3031323335363738393a3b3c3f4041424344454648494d4e4f5051525354555657595a5c5e5f6061626364656667686a6d6e7071727375767778797a7b7c7d7e7f8081838485868788898a8b8c8d8e8f9091929394959697989a9b9c9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b8b9babbbcbdbebfc0c1c2c3c4c6c7c8c9cacbcccecfd0d1d2d3d4d5d6d7d8d9dadcdfe0e3e4eaeced#f0f5f6f8f9fafbfcff,5e:000407090a0b0d0e1213171e1f20212223242528292a2b2c2f303233343536393a3e3f404143464748494a4b4d4e4f50515253565758595a5c5d5f60636465666768696a6b6c6d6e6f70717577797e8182838588898c8d8e92989b9da1a2a3a4a8a9aaabacaeafb0b1b2b4babbbcbdbfc0c1c2c3c4c5c6c7c8cbcccdcecfd0d4d5d7d8d9dadcdddedfe0e1e2e3e4e5e6e7e9ebecedeeeff0f1f2f3f5f8f9fbfcfd,5f:050607090c0d0e10121416191a1c1d1e21222324#282b2c2e30323334353637383b3d3e3f4142434445464748494a4b4c4d4e4f5154595a5b5c5e5f60636567686b6e6f72747576787a7d7e7f83868d8e8f919394969a9b9d9e9fa0a2a3a4a5a6a7a9abacafb0b1b2b3b4b6b8b9babbbebfc0c1c2c7c8cacbced3d4d5dadbdcdedfe2e3e5e6e8e9eceff0f2f3f4f6f7f9fafc,60:0708090b0c10111317181a1e1f2223242c2d2e3031323334363738393a3d3e404445464748494a4c4e4f5153545657585b5c5e5f606165666e71727475777e80#8182858687888a8b8e8f909193959798999c9ea1a2a4a5a7a9aaaeb0b3b5b6b7b9babdbebfc0c1c2c3c4c7c8c9cccdcecfd0d2d3d4d6d7d9dbdee1e2e3e4e5eaf1f2f5f7f8fbfcfdfeff,61:02030405070a0b0c1011121314161718191b1c1d1e21222528292a2c2d2e2f303132333435363738393a3b3c3d3e4041424344454647494b4d4f50525354565758595a5b5c5e5f606163646566696a6b6c6d6e6f717273747678797a7b7c7d7e7f808182838485868788898a8c8d8f9091929395#969798999a9b9c9e9fa0a1a2a3a4a5a6aaabadaeafb0b1b2b3b4b5b6b8b9babbbcbdbfc0c1c3c4c5c6c7c9cccdcecfd0d3d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e7e8e9eaebecedeeeff0f1f2f3f4f6f7f8f9fafbfcfdfe,62:00010203040507091314191c1d1e2023262728292b2d2f303132353638393a3b3c424445464a4f50555657595a5c5d5e5f6061626465687172747577787a7b7d818283858687888b8c8d8e8f9094999c9d9ea3a6a7a9aaadaeafb0b2b3b4b6b7b8babec0c1#c3cbcfd1d5dddee0e1e4eaebf0f2f5f8f9fafb,63:00030405060a0b0c0d0f10121314151718191c2627292c2d2e30313334353637383b3c3e3f40414447484a51525354565758595a5b5c5d60646566686a6b6c6f707273747578797c7d7e7f81838485868b8d9193949597999a9b9c9d9e9fa1a4a6abafb1b2b5b6b9bbbdbfc0c1c2c3c5c7c8cacbccd1d3d4d5d7d8d9dadbdcdddfe2e4e5e6e7e8ebeceeeff0f1f3f5f7f9fafbfcfe,64:0304060708090a0d0e111215161718191a1d1f222324#252728292b2e2f3031323335363738393b3c3e404243494b4c4d4e4f505153555657595a5b5c5d5f60616263646566686a6b6c6e6f70717273747576777b7c7d7e7f8081838688898a8b8c8d8e8f90939497989a9b9c9d9fa0a1a2a3a5a6a7a8aaabafb1b2b3b4b6b9bbbdbebfc1c3c4c6c7c8c9cacbcccfd1d3d4d5d6d9dadbdcdddfe0e1e3e5e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,65:01020304050607080a0b0c0d0e0f10111314151617191a1b1c1d1e1f2021#222324262728292a2c2d30313233373a3c3d404142434446474a4b4d4e5052535457585a5c5f606164656768696a6d6e6f7173757678797a7b7c7d7e7f8081828384858688898a8d8e8f92949596989a9d9ea0a2a3a6a8aaacaeb1b2b3b4b5b6b7b8babbbebfc0c2c7c8c9cacdd0d1d3d4d5d8d9dadbdcdddedfe1e3e4eaebf2f3f4f5f8f9fbfcfdfeff,66:0104050708090b0d1011121617181a1b1c1e2122232426292a2b2c2e3032333738393a3b3d3f40424445464748494a4d4e505158#595b5c5d5e6062636567696a6b6c6d7172737578797b7c7d7f808183858688898a8b8d8e8f909293949598999a9b9c9e9fa0a1a2a3a4a5a6a9aaabacadafb0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8dadedfe0e1e2e3e4e5e7e8eaebecedeeeff1f5f6f8fafbfd,67:010203040506070c0e0f1112131618191a1c1e20212223242527292e303233363738393b3c3e3f414445474a4b4d5254555758595a5b5d62636466676b6c6e717476#78797a7b7d8082838586888a8c8d8e8f9192939496999b9fa0a1a4a6a9acaeb1b2b4b9babbbcbdbebfc0c2c5c6c7c8c9cacbcccdced5d6d7dbdfe1e3e4e6e7e8eaebedeef2f5f6f7f8f9fafbfcfe,68:01020304060d1012141518191a1b1c1e1f20222324252627282b2c2d2e2f30313435363a3b3f474b4d4f52565758595a5b5c5d5e5f6a6c6d6e6f707172737578797a7b7c7d7e7f8082848788898a8b8c8d8e90919294959698999a9b9c9d9e9fa0a1a3a4a5a9aaabacaeb1b2b4b6b7b8#b9babbbcbdbebfc1c3c4c5c6c7c8cacccecfd0d1d3d4d6d7d9dbdcdddedfe1e2e4e5e6e7e8e9eaebecedeff2f3f4f6f7f8fbfdfeff,69:00020304060708090a0c0f11131415161718191a1b1c1d1e21222325262728292a2b2c2e2f313233353637383a3b3c3e4041434445464748494a4b4c4d4e4f50515253555658595b5c5f616264656768696a6c6d6f7072737475767a7b7d7e7f8183858a8b8c8e8f909192939697999a9d9e9fa0a1a2a3a4a5a6a9aaacaeafb0b2b3b5b6b8b9babcbd#bebfc0c2c3c4c5c6c7c8c9cbcdcfd1d2d3d5d6d7d8d9dadcdddee1e2e3e4e5e6e7e8e9eaebeceeeff0f1f3f4f5f6f7f8f9fafbfcfe,6a:000102030405060708090b0c0d0e0f10111213141516191a1b1c1d1e20222324252627292b2c2d2e30323334363738393a3b3c3f40414243454648494a4b4c4d4e4f515253545556575a5c5d5e5f60626364666768696a6b6c6d6e6f70727374757677787a7b7d7e7f81828385868788898a8b8c8d8f929394959698999a9b9c9d9e9fa1a2a3a4a5a6#a7a8aaadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,6b:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f252628292a2b2c2d2e2f303133343536383b3c3d3f4041424445484a4b4d4e4f5051525354555657585a5b5c5d5e5f606168696b6c6d6e6f7071727374757677787a7d7e7f808588#8c8e8f909194959798999c9d9e9fa0a2a3a4a5a6a7a8a9abacadaeafb0b1b2b6b8b9babbbcbdbec0c3c4c6c7c8c9caccced0d1d8dadcdddedfe0e2e3e4e5e6e7e8e9ecedeef0f1f2f4f6f7f8fafbfcfeff,6c:000102030408090a0b0c0e12171c1d1e2023252b2c2d31333637393a3b3c3e3f434445484b4c4d4e4f5152535658595a62636566676b6c6d6e6f71737577787a7b7c7f8084878a8b8d8e9192959697989a9c9d9ea0a2a8acafb0b4b5b6b7bac0c1c2c3c6c7c8cbcdcecfd1d2d8#d9dadcdddfe4e6e7e9ecedf2f4f9ff,6d:000203050608090a0d0f101113141516181c1d1f20212223242628292c2d2f30343637383a3f404244494c50555657585b5d5f6162646567686b6c6d707172737576797a7b7d7e7f8081838486878a8b8d8f9092969798999a9ca2a5acadb0b1b3b4b6b7b9babbbcbdbec1c2c3c8c9cacdcecfd0d2d3d4d5d7dadbdcdfe2e3e5e7e8e9eaedeff0f2f4f5f6f8fafdfeff,6e:0001020304060708090b0f12131518191b1c1e1f222627282a2c2e30313335#3637393b3c3d3e3f40414245464748494a4b4c4f5051525557595a5c5d5e606162636465666768696a6c6d6f707172737475767778797a7b7c7d8081828487888a8b8c8d8e91929394959697999a9b9d9ea0a1a3a4a6a8a9abacadaeb0b3b5b8b9bcbebfc0c3c4c5c6c8c9cacccdced0d2d6d8d9dbdcdde3e7eaebecedeeeff0f1f2f3f5f6f7f8fafbfcfdfeff,6f:000103040507080a0b0c0d0e101112161718191a1b1c1d1e1f212223252627282c2e303234353738393a3b3c3d3f404142#43444548494a4c4e4f5051525354555657595a5b5d5f60616364656768696a6b6c6f707173757677797b7d7e7f808182838586878a8b8f909192939495969798999a9b9d9e9fa0a2a3a4a5a6a8a9aaabacadaeafb0b1b2b4b5b7b8babbbcbdbebfc1c3c4c5c6c7c8cacbcccdcecfd0d3d4d5d6d7d8d9dadbdcdddfe2e3e4e5e6e7e8e9eaebecedf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,70:000102030405060708090a0b0c0d0e0f1012131415161718191c1d1e1f2021222425262728292a#2b2c2d2e2f30313233343637383a3b3c3d3e3f404142434445464748494a4b4d4e505152535455565758595a5b5c5d5f606162636465666768696a6e7172737477797a7b7d818283848687888b8c8d8f90919397989a9b9e9fa0a1a2a3a4a5a6a7a8a9aab0b2b4b5b6babebfc4c5c6c7c9cbcccdcecfd0d1d2d3d4d5d6d7dadcdddee0e1e2e3e5eaeef0f1f2f3f4f5f6f8fafbfcfeff,71:0001020304050607080b0c0d0e0f111214171b1c1d1e1f2021222324252728292a2b2c2d2e323334#353738393a3b3c3d3e3f4041424344464748494b4d4f505152535455565758595a5b5d5f6061626365696a6b6c6d6f707174757677797b7c7e7f8081828385868788898b8c8d8e909192939596979a9b9c9d9ea1a2a3a4a5a6a7a9aaabadaeafb0b1b2b4b6b7b8babbbcbdbebfc0c1c2c4c5c6c7c8c9cacbcccdcfd0d1d2d3d6d7d8d9dadbdcdddedfe1e2e3e4e6e8e9eaebecedeff0f1f2f3f4f5f6f7f8fafbfcfdfeff,72:0001020304050708090a0b0c0d0e0f101112131415161718191a#1b1c1e1f2021222324252627292b2d2e2f3233343a3c3e40414243444546494a4b4e4f505153545557585a5c5e60636465686a6b6c6d707173747677787b7c7d828385868788898c8e9091939495969798999a9b9c9d9ea0a1a2a3a4a5a6a7a8a9aaabaeb1b2b3b5babbbcbdbebfc0c5c6c7c9cacbcccfd1d3d4d5d6d8dadb#95$,30:000102,00b702:c9c7,00a830:0305,2014ff5e20:162618191c1d,30:141508090a0b0c0d0e0f16171011,00:b1d7f7,22:362728110f2a2908371aa52520,231222:992b2e614c483d1d606e6f64651e3534,26:4240,00b020:3233,2103ff0400a4ff:e0e1,203000a7211626:0605,25:cbcfcec7c6a1a0b3b2,203b21:92909193,30:13#95$,21:70717273747576777879#4$,24:88898a8b8c8d8e8f909192939495969798999a9b7475767778797a7b7c7d7e7f808182838485868760616263646566676869##,32:20212223242526272829##,21:606162636465666768696a6b#97$,ff:010203e505060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5de3#95$,30:4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293#106$a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6#103$,03:9192939495969798999a9b9c9d9e9fa0a1a3a4a5a6a7a8a9#6$b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c3c4c5c6c7c8c9#5$,fe:3536393a3f403d3e41424344##3b3c373831#3334#104$,04:10111213141501161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f#13$30313233343551363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f#11$,02:cacbd9,20:13152535,21:050996979899,22:151f23526667bf,25:505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727381828384858687#88898a8b8c8d8e8f939495bcbde2e3e4e5,2609229530:121d1e#9$,010100e101ce00e0011300e9011b00e8012b00ed01d000ec014d00f301d200f2016b00fa01d400f901:d6d8dadc,00:fcea,0251e7c701:4448,e7c802:61#2$,31:05060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829#19$,30:212223242526272829,32a333:8e8f9c9d9ea1c4ced1d2d5,fe30ff:e2e4#,212132:31#,20:10#1$,30:fc9b9cfdfe069d9e,fe:494a4b4c4d4e4f50515254555657595a5b5c5d5e5f6061#626364656668696a6b,e7:e7e8e9eaebecedeeeff0f1f2f3,30:07#11$,25:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b#13$,72:dcdddfe2e3e4e5e6e7eaebf5f6f9fdfeff,73:00020405060708090b0c0d0f1011121418191a1f2023242627282d2f30323335363a3b3c3d404142434445464748#494a4b4c4e4f515354555658595a5b5c5d5e5f6162636465666768696a6b6e7071#92$72737475767778797a7b7c7d7f808182838586888a8c8d8f90929394959798999a9c9d9ea0a1a3a4a5a6a7a8aaacadb1b4b5b6b8b9bcbdbebfc1c3c4c5c6c7#cbccced2d3d4d5d6d7d8dadbdcdddfe1e2e3e4e6e8eaebeceeeff0f1f3f4f5f6f7#92$f8f9fafbfcfdfeff,74:0001020407080b0c0d0e1112131415161718191c1d1e1f2021232427292b2d2f31323738393a3b3d3e3f4042434445464748494a4b4c4d#4e4f505152535456585d606162636465666768696a6b6c6e6f717273747578797a#92$7b7c7d7f8284858688898a8c8d8f9192939495969798999a9b9d9fa0a1a2a3a4a5a6aaabacadaeafb0b1b2b3b4b5b6b7b8b9bbbcbdbebfc0c1c2c3c4c5c6c7#c8c9cacbcccdcecfd0d1d3d4d5d6d7d8d9dadbdddfe1e5e7e8e9eaebecedf0f1f2#92$f3f5f8f9fafbfcfdfe,75:0001020305060708090a0b0c0e1012141516171b1d1e202122232426272a2e3436393c3d3f414243444647494a4d5051525355565758#5d5e5f60616263646768696b6c6d6e6f7071737576777a7b7c7d7e808182848587#92$88898a8c8d8e909395989b9c9ea2a6a7a8a9aaadb6b7babbbfc0c1c6cbcccecfd0d1d3d7d9dadcdddfe0e1e5e9ecedeeeff2f3f5f6f7f8fafbfdfe,76:02040607#08090b0d0e0f11121314161a1c1d1e212327282c2e2f31323637393a3b3d414244#92$45464748494a4b4e4f50515253555758595a5b5d5f6061626465666768696a6c6d6e7071727374757677797a7c7f80818385898a8c8d8f9092949597989a9b#9c9d9e9fa0a1a2a3a5a6a7a8a9aaabacadafb0b3b5b6b7b8b9babbbcbdbec0c1c3,554a963f57c3632854ce550954c076:914c,853c77ee827e788d72319698978d6c285b894ffa630966975cb880fa684880ae660276ce51f9655671ac7ff1888450b2596561ca6fb382ad634c625253ed54277b06516b75a45df462d48dcb9776628a8019575d97387f627238767d67cf767e64464f708d2562dc7a17659173ed642c6273822c9881677f724862:6ecc,4f3474e3534a529e7eca90a65e2e6886699c81807ed168d278c5868c9551508d8c2482de80de53058912526576:c4c7c9cbccd3d5d9dadcdddee0e1e2e3e4e6e7e8e9eaebecedf0f3f5f6f7fafbfdff,77:00020305060a0c0e0f1011121314151617181b1c1d1e21232425272a2b#2c2e3031323334393b3d3e3f4244454648494a4b4c4d4e4f52535455565758595c,858496f94fdd582199715b9d62:b1a5,66b48c799c8d7206676f789160b253:5117,8f8880cc8d1d94a1500d72c8590760eb711988ab595482ef672c7b285d297ef7752d6cf58e668ff8903c9f3b6bd491197b145f7c78a784d6853d6b:d5d9d6,5e:0187,75f995ed655d5f:0ac5,8f9f58c181c2907f965b97ad8fb97f168d2c62414fbf53:d85e,8f:a8a9ab,904d68075f6a819888689cd6618b522b762a5f6c658c6fd26ee85bbe644851:75b0,67c44e1979c9997c70b377:5d5e5f606467696a6d6e6f7071727374757677787a7b7c818283868788898a8b8f90939495969798999a9b9c9d9ea1a3a4a6a8abadaeafb1b2b4b6b7b8b9ba#bcbec0c1c2c3c4c5c6c7c8c9cacbcccecfd0d1d2d3d4d5d6d8d9dadddedfe0e1e4,75c55e7673bb83e064ad62e894b56ce2535a52c3640f94c27b944f2f5e1b823681:168a,6e246cca9a736355535c54fa886557e04e0d5e036b657c3f90e8601664e6731c88c16750624d8d22776c8e2991c75f6983dc8521991053c286956b8b60:ede8,707f82:cd31,4ed36ca785cf64cd7cd969fd66f9834953957b564fa7518c6d4b5c428e6d63d253c983:2c36,67e578b4643d5bdf5c945dee8be762c667f48c7a640063ba8749998b8c177f2094f24ea7961098a4660c731677:e6e8eaeff0f1f2f4f5f7f9fafbfc,78:0304050607080a0b0e0f101315191b1e20212224282a2b2e2f31323335363d3f414243444648494a4b4d4f51535458595a#5b5c5e5f606162636465666768696f7071727374757678797a7b7d7e7f80818283,573a5c1d5e38957f507f80a05382655e7545553150218d856284949e671d56326f6e5de2543570928f66626f64a463a35f7b6f8890f481e38fb05c1866685ff16c8996488d81886c649179f057ce6a59621054484e587a0b60e96f848bda627f901e9a8b79e4540375f4630153196c608fdf5f1b9a70803b9f7f4f885c3a8d647fc565a570bd51:45b2,866b5d075ba062bd916c75748e0c7a2061017b794ec77ef877854e1181ed521d51fa6a7153a88e87950496cf6ec19664695a78:848586888a8b8f9092949596999d9ea0a2a4a6a8a9aaabacadaeafb5b6b7b8babbbcbdbfc0c2c3c4c6c7c8cccdcecfd1d2d3d6d7d8dadbdcdddedfe0e1e2e3#e4e5e6e7e9eaebedeeeff0f1f3f5f6f8f9fbfcfdfeff,79:00020304060708090a0b0c,784050a877d7641089e6590463e35ddd7a7f693d4f20823955984e3275ae7a975e:628a,95ef521b5439708a6376952457826625693f918755076df37eaf882262337ef075b5832878c196cc8f9e614874f78bcd6b64523a8d506b21806a847156f153064e:ce1b,51d17c97918b7c074fc38e7f7be17a9c64675d1450ac810676017cb96dec7fe067515b:58f8,78cb64:ae13,63:aa2b,9519642d8fbe7b5476296253592754466b7950a362345e266b864ee38d37888b5f85902e79:0d0e0f1011121415161718191a1b1c1d1f2021222325262728292a2b2c2d2e2f3031323335363738393d3f42434445474a4b4c4d4e4f505152545558596163#6466696a6b6c6e70717273747576797b7c7d7e7f8283868788898b8c8d8e909192,6020803d62c54e39535590f863b880c665e66c2e4f4660ee6de18bde5f3986cb5f536321515a83616863520063638e4850125c9b79775bfc52307a3b60bc905376d75f:b797,76848e6c706f767b7b4977aa51f3909358244f4e6ef48fea654c7b1b72c46da47fdf5ae162b55e95573084827b2c5e1d5f1f90127f1498a063826ec7789870b95178975b57ab75354f4375385e9760e659606dc06bbf788953fc96d551cb52016389540a94938c038dcc7239789f87768fed8c0d53e079:939495969798999b9c9d9e9fa0a1a2a3a4a5a6a8a9aaabacadaeafb0b1b2b4b5b6b7b8bcbfc2c4c5c7c8cacccecfd0d3d4d6d7d9dadbdcdddee0e1e2e5e8ea#eceef1f2f3f4f5f6f7f9fafcfeff,7a:0104050708090a0c0f10111213151618191b1c,4e0176ef53ee948998769f0e952d5b9a8ba24e:221c,51ac846361c252a8680b4f97606b51bb6d1e515c6296659796618c46901775d890fd77636bd272:8aec,8bfb583577798d4c675c9540809a5ea66e2159927aef77ed953b6bb565ad7f0e58065151961f5bf958a954288e726566987f56e4949d76fe9041638754c659:1a3a,579b8eb267358dfa8235524160f0581586fe5ce89e454fc4989d8bb95a2560765384627c904f9102997f6069800c513f80335c1499756d314e8c7a:1d1f21222425262728292a2b2c2d2e2f303132343536383a3e4041424344454748494a4b4c4d4e4f50525354555658595a5b5c5d5e5f606162636465666768#696a6b6c6d6e6f717273757b7c7d7e828587898a8b8c8e8f909394999a9b9ea1a2,8d3053d17f5a7b4f4f104e4f96006cd573d085e95e06756a7ffb6a0a77fe94927e4151e170e653cd8fd483038d2972af996d6cdb574a82b365b980aa623f963259a84eff8bbf7eba653e83f2975e556198de80a5532a8bfd542080ba5e9f6cb88d3982ac915a54296c1b52067eb7575f711a6c7e7c89594b4efd5fff61247caa4e305c0167ab87025cf0950b98ce75af70fd902251af7f1d8bbd594951e44f5b5426592b657780a45b7562:76c2,8f905e456c1f7b264f:0fd8,670d7a:a3a4a7a9aaabaeafb0b1b2b4b5b6b7b8b9babbbcbdbec0c1c2c3c4c5c6c7c8c9cacccdcecfd0d1d2d3d4d5d7d8dadbdcdde1e2e4e7e8e9eaebeceef0f1f2f3#f4f5f6f7f8fbfcfe,7b:0001020507090c0d0e1012131617181a1c1d1f21222327292d,6d:6eaa,798f88b15f17752b629a8f854fef91dc65a781:2f51,5e9c81508d74526f89868d4b590d50854ed8961c723681798d1f5bcc8ba3964459877f1a549056:760e,8be565396982949976d66e895e72751867:46d1,7aff809d8d76611f79c665628d635188521a94a27f38809b7eb25c976e2f67607bd9768b9ad8818f7f947cd5641e95507a3f54:4ae5,6b4c640162089e3d80f3759952729769845b683c86e496:0194,94ec4e2a54047ed968398ddf801566f45e9a7fb97b:2f303234353637393b3d3f404142434446484a4d4e535557595c5e5f61636465666768696a6b6c6d6f70737476787a7c7d7f81828384868788898a8b8c8e8f#9192939698999a9b9e9fa0a3a4a5aeafb0b2b3b5b6b7b9babbbcbdbebfc0c2c3c4,57c2803f68975de5653b529f606d9f9a4f9b8eac516c5bab5f135de96c5e62f18d21517194a952fe6c9f82df72d757a267848d2d591f8f9c83c754957b8d4f306cbd5b6459d19f1353e486ca9aa88c3780a16545987e56fa96c7522e74dc52505be1630289024e5662d0602a68fa51735b9851a089c27ba199867f5060ef704c8d2f51495e7f901b747089c4572d78455f529f9f95fa8f689b3c8be17678684267dc8d:ea35,523d8f8a6eda68cd950590ed56fd679c88f98fc754c87b:c5c8c9cacbcdcecfd0d2d4d5d6d7d8dbdcdedfe0e2e3e4e7e8e9ebecedeff0f2f3f4f5f6f8f9fafbfdff,7c:0001020304050608090a0d0e101112131415171819#1a1b1c1d1e20212223242528292b2c2d2e2f3031323334353637393a3b3c3d3e42,9ab85b696d776c264ea55bb39a87916361a890af97e9542b6db55bd251fd558a7f:55f0,64bc634d65f161be608d710a6c:5749,592f676d822a58d5568e8c6a6beb90dd597d801753f76d695475559d83:77cf,683879be548c4f55540876d28c8996026cb36db88d6b89109e648d3a563f9ed175d55f8872e0606854fc4ea86a2a886160528f7054c470d886799e3f6d2a5b8f5f187ea255894faf7334543c539a501954:0e7c,4e4e5ffd745a58f6846b80e1877472d07cca6e567c:434445464748494a4b4c4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717275767778797a7e7f8081828384858687#888a8b8c8d8e8f90939496999a9ba0a1a3a6a7a8a9abacadafb0b4b5b6b7b8babb,5f27864e552c62a44e926caa623782b154d7534e733e6ed1753b521253168bdd69d05f8a60006dee574f6b2273af68538fd87f13636260a3552475ea8c6271156da35ba65e7b8352614c9ec478fa87577c27768751f060f6714c66435e4c604d8c0e707063258f895fbd606286d456de6bc160946167534960e066668d3f79fd4f1a70e96c478b:b3f2,7ed88364660f5a5a9b426d:51f7,8c416d3b4f19706b83b7621660d1970d8d27797851fb57:3efa,673a75787a3d79ef7b957c:bfc0c2c3c4c6c9cbcecfd0d1d2d3d4d8dadbdddee1e2e3e4e5e6e7e9eaebecedeef0f1f2f3f4f5f6f7f9fafcfdfeff,7d:000102030405060708090b0c0d0e0f10#1112131415161718191a1b1c1d1e1f212324252628292a2c2d2e30313233343536,808c99658ff96fc08ba59e2159ec7ee97f095409678168d88f917c4d96c653ca602575be6c7253735ac97ea7632451e0810a5df184df628051805b634f0e796d524260b86d4e5b:c4c2,8b:a1b0,65e25fcc964559937e:e7aa,560967b759394f735bb652a0835a988a8d3e753294be50477a3c4ef767b69a7e5ac16b7c76d1575a5c167b3a95f4714e517c80a9827059787f04832768c067ec78:b177,62e363617b804fed526a51cf835069db92748d:f531,89c1952e7bad4ef67d:3738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6f70717273747576#78797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798,506582305251996f6e:1085,6da75efa50f559dc5c066d466c5f7586848b686859568bb253209171964d854969127901712680f64ea490ca6d479a845a0756bc640594f077eb4fa5811a72e189d2997a7f347ede527f655991758f:7f83,53eb7a9663:eda5,768679f888579636622a52ab8282685467706377776b7aed6d017ed389e359d0621285c982a5754c501f4ecb75a58beb5c4a5dfe7b4b65a491d14eca6d25895f7d2795264ec58c288fdb9773664b79818fd170ec6d787d:999a9b9c9d9e9fa0a1a2a3a4a5a7a8a9aaabacadafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9#dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa,5c3d52b283465162830e775b66769cb84eac60ca7c:beb3,7ecf4e958b66666f988897595883656c955c5f8475c997567a:dfde,51c070af7a9863ea7a767ea0739697ed4e4570784e5d915253a965:51e7,81fc8205548e5c31759a97a062d872d975bd5c459a7983ca5c40548077e94e3e6cae805a62d2636e5de851778ddd8e1e952f4ff153e560e770ac526763509e435a1f5026773753777ee26485652b628963985014723589c951b38bc07edd574783cc94a7519b541b5cfb7d:fbfcfdfeff,7e:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839#3a3c3d3e3f40424344454648494a4b4c4d4e4f505152535455565758595a5b5c5d,4fca7ae36d5a90e19a8f55805496536154af5f0063e9697751ef6168520a582a52d8574e780d770b5eb761777ce062:5b97,4ea27095800362f770e49760577782db67ef68f578d5989779d158f354b353ef6e34514b523b5ba28bfe80af554357a660735751542d7a7a60505b5463a762a053e362635bc767af54ed7a9f82e691775e9388e4593857ae630e8de880ef57577b774fa95feb5bbd6b3e53217b5072c2684677:ff36,65f751b54e8f76d45cbf7aa58475594e9b4150807e:5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081838485868788898a8b8c8d8e8f909192939495969798999a9c9d9e#aeb4bbbcd6e4ecf9,7f:0a101e37393b3c3d3e3f404143464748494a4b4c4d4e4f5253,998861276e8357646606634656f062:ec69,5ed39614578362c955878721814a8fa3556683b167658d5684dd5a6a680f62e67bee961151706f9c8c3063fd89c861d27f0670c26ee57405699472fc5eca90ce67176d6a635e52b3726280014f6c59e5916a70d96d9d52d24e5096f7956d857e78ca7d2f5121579264c2808b7c7b6cea68f1695e51b7539868a872819ece7bf172f879bb6f137406674e91cc9ca4793c83:8954,540f68174e3d538952b1783e5386522950884f:8bd0,7f:56595b5c5d5e6063646566676b6c6d6f7073757677787a7b7c7d7f8082838485868788898b8d8f9091929395969798999b9ca0a2a3a5a6a8a9aaabacadaeb1#b3b4b5b6b7babbbec0c2c3c4c6c7c8c9cbcdcfd0d1d2d3d6d7d9dadbdcdddee2e3,75e27acb7c926ca596b6529b748354e94fe9805483b28fde95705ec9601c6d9f5e18655b813894fe604b70bc7ec37cae51c968817cb1826f4e248f8691cf667e4eae8c0564a9804a50da759771ce5be58fbd6f664e86648295635ed66599521788c270c852a3730e7433679778f797164e3490bb9cde6dcb51db8d41541d62ce73b283f196f69f8494c34f367f9a51cc707596755cad988653e64ee46e9c740969b4786b998f7559521876246d4167f3516d9f99804b54997b3c7abf7f:e4e7e8eaebecedeff2f4f5f6f7f8f9fafdfeff,80:020708090a0e0f11131a1b1d1e1f2123242b2c2d2e2f303234393a3c3e404144454748494e4f505153555657#595b5c5d5e5f6061626364656667686b6c6d6e6f7072737475767778797a7b7c7d,9686578462e29647697c5a0464027bd36f0f964b82a6536298855e90708963b35364864f9c819e93788c97328d:ef42,9e7f6f5e79845f559646622e9a74541594dd4fa365c55c:6561,7f1586516c2f5f8b73876ee47eff5ce6631b5b6a6ee653754e7163a0756562a18f6e4f264ed16ca67eb68bba841d87ba7f57903b95237ba99aa188f8843d6d1b9a867edc59889ebb739b780186829a:6c82,561b541757cb4e709ea653568fc881097792999286ee6ee1851366fc61626f2b80:7e818285888a8d8e8f909192949597999ea3a6a7a8acb0b3b5b6b8b9bbc5c7c8c9cacbcfd0d1d2d3d4d5d8dfe0e2e3e6eef5f7f9fbfeff,81:000103040507080b#0c1517191b1c1d1f202122232425262728292a2b2d2e3033343537393a3b3c3d3f,8c298292832b76f26c135fd983bd732b8305951a6bdb77db94c6536f830251925e3d8c8c8d384e4873ab679a68859176970971646ca177095a9295416bcf7f8e66275bd059b95a9a95:e8f7,4eec84:0c99,6aac76df9530731b68a65b5f772f919a97617cdc8ff78c1c5f257c7379d889c56ccc871c5bc65e4268c977207ef551:954d,52c95a297f05976282d763cf778485d079d26e3a5e9959998511706d6c1162bf76bf654f60af95fd660e879f9e2394ed54:0d7d,8c2c647881:40414243444547494d4e4f525657585b5c5d5e5f6162636466686a6b6c6f727375767778818384858687898b8c8d8e90929394959697999a9e9fa0a1a2a4a5#a7a9abacadaeafb0b1b2b4b5b6b7b8b9bcbdbebfc4c5c7c8c9cbcdcecfd0d1d2d3,647986116a21819c78e864699b5462b9672b83ab58a89ed86cab6f205bde964c8c0b725f67d062c772614ea959c66bcd589366ae5e5552df6155672876ee776672677a4662ff54:ea50,94a090a35a1c7eb36c164e435976801059485357753796be56ca63208111607c95f96dd65462998151855ae980fd59ae9713502a6ce55c3c62df4f60533f817b90066eba852b62c85e7478be64b5637b5ff55a18917f9e1f5c3f634f80425b7d556e95:4a4d,6d8560a867e072de51dd5b8181:d4d5d6d7d8d9dadbdcdddedfe0e1e2e4e5e6e8e9ebeeeff0f1f2f5f6f7f8f9fafdff,82:030708090a0b0e0f111315161718191a1d2024252627292e323a3c3d3f#404142434546484a4c4d4e5051525354555657595b5c5d5e606162636465666769,62e76cde725b626d94ae7ebd81136d53519c5f04597452aa6012597366968650759f632a61e67cef8bfa54e66b279e256bb485d5545550766ca4556a8db4722c5e156015743662cd6392724c5f986e436d3e65006f5876d878d076fc7554522453db4e535e9e65c180:2ad6,629b5486522870ae888d8dd16ce1547880da57f988f48d54966a914d4f696c9b55b776c6783062a870f96f8e5f6d84ec68da787c7bf781a8670b9e4f636778b0576f7812973962:79ab,528874356bd782:6a6b6c6d71757677787b7c808183858687898c90939495969a9b9ea0a2a3a7b2b5b6babbbcbfc0c2c3c5c6c9d0d6d9dadde2e7e8e9eaecedeef0f2f3f5f6f8#fafcfdfeff,83:000a0b0d1012131618191d1e1f20212223242526292a2e3032373b3d,5564813e75b276ae533975de50fb5c418b6c7bc7504f72479a9798d86f0274e27968648777a562fc98918d2b54c180584e52576a82f9840d5e7351ed74f68bc45c4f57616cfc98875a4678349b448feb7c955256625194fa4ec68386846183e984b257d467345703666e6d668c3166dd7011671f6b3a6816621a59bb4e0351c46f0667d26c8f517668cb59476b6775665d0e81109f5065d779:4841,9a918d775c824e5e4f01542f5951780c56686c148fc45f036c:7de3,8bab639083:3e3f41424445484a4b4c4d4e5355565758595d6270717273747576797a7e7f808182838487888a8b8c8d8f909194959697999a9d9fa1a2a3a4a5a6a7acadae#afb5bbbebfc2c3c4c6c8c9cbcdced0d1d2d3d5d7d9dadbdee2e3e4e6e7e8ebeced,60706d3d7275626694:8ec5,53438fc17b7e4edf8c264e7e9ed494:b1b3,524d6f5c90636d458c3458115d4c6b:2049,67aa545b81547f8c589985375f3a62a26a47953965726084686577a74e544fa85de7979864ac7fd85ced4fcf7a8d520783044e14602f7a8394a64fb54eb279e6743452e482b964d279bd5bdd6c8197528f7b6c22503e537f6e0564ce66746c3060c598778bf75e86743c7a7779cb4e1890b174036c4256da914b6cc58d8b533a86c666f28eaf5c489a716e2083:eeeff3f4f5f6f7fafbfcfeff,84:0002050708090a10121314151617191a1b1e1f20212223292a2b2c2d2e2f30323334353637393a3b3e3f404142434445474849#4a4b4c4d4e4f505253545556585d5e5f606264656667686a6e6f70727477797b7c,53d65a369f8b8da353bb570898a76743919b6cc9516875ca62f372ac52:389d,7f3a7094763853749e4a69b7786e96c088d97fa471:36c3,518967d374e458e4651856b78ba9997662707ed560f970ed58ec4e:c1ba,5fcd97e74efb8ba45203598a7eab62544ecd65e5620e833884c98363878d71946eb65bb97ed2519763c967d480898339881551125b7a59828fb14e736c5d516589258f6f962e854a745e95:10f0,6da682e55f3164926d128428816e9cc3585e8d5b4e0953c184:7d7e7f8081838485868a8d8f90919293949596989a9b9d9e9fa0a2a3a4a5a6a7a8a9aaabacadaeb0b1b3b5b6b7bbbcbec0c2c3c5c6c7c8cbcccecfd2d4d5d7#d8d9dadbdcdee1e2e4e7e8e9eaebedeeeff1f2f3f4f5f6f7f8f9fafbfdfe,85:000102,4f1e6563685155d34e2764149a9a626b5ac2745f82726da968ee50e7838e7802674052396c997eb150bb5565715e7b5b665273ca82eb67495c715220717d886b95ea965564c58d6181b355846c5562477f2e58924f2455468d4f664c4e0a5c1a88f368a2634e7a0d70e7828d52fa97f65c1154e890b57ecd59628d4a86c782:0c0d,8d6664445c0461516d89793e8bbe78377533547b4f388eab6df15a207ec5795e6c885ba15a76751a80be614e6e1758f075:1f25,727253477ef385:030405060708090a0b0d0e0f101214151618191b1c1d1e2022232425262728292a2d2e2f303132333435363e3f404142444546474b4c4d4e4f505152535455#57585a5b5c5d5f60616263656667696a6b6c6d6e6f707173757677787c7d7f8081,770176db526980dc57235e08593172ee65bd6e7f8bd75c388671534177f362fe65f64ec098df86805b9e8bc653f277e24f7f5c4e9a7659cb5f0f793a58eb4e1667ff4e8b62ed8a93901d52bf662f55dc566c90024ed54f8d91ca99706c0f5e0260435ba489c68bd56536624b99965b:88ff,6388552e53d77626517d852c67a268b36b8a62928f9353d482126dd1758f4e668d4e5b70719f85af66:91d9,7f7287009ecd9f205c5e672f8ff06811675f620d7ad658855eb665706f3185:82838688898a8b8c8d8e909192939495969798999a9d9e9fa0a1a2a3a5a6a7a9abacadb1b2b3b4b5b6b8babbbcbdbebfc0c2c3c4c5c6c7c8cacbcccdced1d2#d4d6d7d8d9dadbdddedfe0e1e2e3e5e6e7e8eaebecedeeeff0f1f2f3f4f5f6f7f8,60555237800d6454887075295e05681362f4971c53cc723d8c016c3477617a0e542e77ac987a821c8bf47855671470c165af64955636601d79c153f84e1d6b7b80865bfa55e356db4f:3a3c,99725df3677e80386002988290015b8b8b:bcf5,641c825864de55fd82cf91654fd77d20901f7c9f50f358516eaf5bbf8bc980839178849c7b97867d96:8b8f,7ee59ad3788e5c817a57904296a7795f5b59635f7b0b84d168ad55067f2974107d2295016240584c4ed65b835979585485:f9fafcfdfe,86:0001020304060708090a0b0c0d0e0f10121314151718191a1b1c1d1e1f20212223242526282a2b2c2d2e2f3031323334353637393a3b3d3e3f40#4142434445464748494a4b4c525355565758595b5c5d5f6061636465666768696a,736d631e8e:4b0f,80ce82d462ac53f06cf0915e592a60016c70574d644a8d2a762b6ee9575b6a8075f06f6d8c:2d08,57666bef889278b363a253f970ad6c645858642a580268e0819b55107cd650188eba6dcc8d9f70eb638f6d9b6ed47ee68404684390036dd896768ba85957727985e4817e75bc8a8a68af52548e22951163d098988e44557c4f5366ff568f60d56d9552435c4959296dfb586b75:301c,606c82148146631167618fe2773a8d:f334,94c15e165385542c70c386:6d6f7072737475767778838485868788898e8f90919294969798999a9b9e9fa0a1a2a5a6abadaeb2b3b7b8b9bbbcbdbebfc1c2c3c5c8cccdd2d3d5d6d7dadc#dde0e1e2e3e5e6e7e8eaebeceff5f6f7fafbfcfdff,87:010405060b0c0e0f10111416,6c405ef7505c4ead5ead633a8247901a6850916e77b3540c94dc5f647ae5687663457b527edf75db507762955934900f51f879c37a8156fe5f9290146d825c60571f541051546e4d56e263a89893817f8715892a9000541e5c6f81c062:d658,81319e3596409a:6e7c,692d59a562d3553e631654c786d96d3c5a0374e6889c6b6a59168c4c5f2f6e7e73a9987d4e3870f75b8c7897633d665a769660cb5b9b5a494e0781556c6a738b4ea167897f515f8065fa671b5fd859845a0187:191b1d1f20242627282a2b2c2d2f303233353638393a3c3d404142434445464a4b4d4f505152545556585a5b5c5d5e5f6162666768696a6b6c6d6f71727375#7778797a7f8081848687898a8c8e8f90919294959698999a9b9c9d9ea0a1a2a3a4,5dcd5fae537197e68fdd684556f4552f60df4e3a6f4d7ef482c7840e59d44f:1f2a,5c3e7eac672a851a5473754f80c355829b4f4f4d6e2d8c135c096170536b761f6e29868a658795fb7eb9543b7a337d0a95ee55e17fc174ee631d87176da17a9d621165a1536763e16c835deb545c94a84e4c6c618bec5c4b65e0829c68a754:3e34,6b:cb66,4e9463425348821e4f:0dae,575e620a96fe6664726952:ffa1,609f8bef661471996790897f785277fd6670563b54389521727a87:a5a6a7a9aaaeb0b1b2b4b6b7b8b9bbbcbebfc1c2c3c4c5c7c8c9cccdcecfd0d4d5d6d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedeff0f1f2f3f4f5f6f7f8#fafbfcfdff,88:0001020405060708090b0c0d0e0f101112141718191a1c1d1e1f2023,7a00606f5e0c6089819d591560dc718470ef6eaa6c5072806a8488ad5e2d4e605ab3559c94e36d177cfb9699620f7ec6778e867e5323971e8f9666875ce14fa072ed4e0b53a6590f54136380952851484ed99c9c7ea454b88d248854823795f26d8e5f265acc663e966973:b02e,53bf817a99857fa15baa96:7750,7ebf76f853a2957699997bb189446e584e617fd479658be660f354cd4eab98795df76a6150cf54118c618427785d9704524a54ee56a395006d885bb56dc6665388:2425262728292a2b2c2d2e2f30313334353637383a3b3d3e3f414243464748494a4b4e4f505152535556585a5b5c5d5e5f6066676a6d6f717374757678797a#7b7c80838687898a8c8e8f90919394959798999a9b9d9e9fa0a1a3a5a6a7a8a9aa,5c0f5b5d6821809655787b11654869544e9b6b47874e978b534f631f643a90aa659c80c18c10519968b0537887f961c86c:c4fb,8c225c5185aa82af950c6b238f9b65b05f:fbc3,4fe18845661f8165732960fa51745211578b5f6290a2884c91925e78674f602759d351:44f6,80f853086c7996c4718a4f:11ee,7f9e673d55c5950879c088967ee3589f620c9700865a5618987b5f908bb884c4915753d965ed5e8f755c60647d6e5a7f7e:eaed,8f6955a75ba360ac65cb738488:acaeafb0b2b3b4b5b6b8b9babbbdbebfc0c3c4c7c8cacbcccdcfd0d1d3d6d7dadbdcdddee0e1e6e7e9eaebecedeeeff2f5f6f7fafbfdff,89:0001030405060708#090b0c0d0e0f1114151617181c1d1e1f20222324262728292c2d2e2f3132333537,9009766377297eda9774859b5b667a7496ea884052cb718f5faa65ec8be25bfb9a6f5de16b896c5b8b:adaf,900a8fc5538b62bc9e:262d,54404e2b82bd7259869c5d1688596daf96c554d14e9a8bb6710954bd960970df6df976d04e25781487125ca95ef68a00989c960e708e6cbf594463a9773c884d6f148273583071d5538c781a96c155015f6671305bb48c1a9a8c6b83592e9e2f79e76768626c4f6f75a17f8a6d0b96336c274ef075d2517b68376f3e908081705996747689:38393a3b3c3d3e3f40424345464748494a4b4c4d4e4f505152535455565758595a5b5c5d6061626364656768696a6b6c6d6e6f707172737475767778797a7c#7d7e808284858788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1,64475c2790657a918c2359da54ac8200836f898180006930564e8036723791ce51b64e5f987563964e1a53f666f3814b591c6db24e0058f9533b63d694f14f:9d0a,886398905937905779fb4eea80f075916c825b9c59e85f5d69058681501a5df24e5977e34ee5827a6291661390915c794ebf5f7981c69038808475ab4ea688d4610f6bc55fc64e4976ca6ea28b:e3ae,8c0a8bd15f027f:fccc,7ece83:356b,56e06bb797f3963459fb541f94f66deb5bc5996e5c395f15969089:a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c3cdd3d4d5d7d8d9dbdddfe0e1e2e4e7e8e9eaecedeef0f1f2f4f5f6f7f8f9fa#fbfcfdfeff,8a:01020304050608090a0b0c0d0e0f101112131415161718191a1b1c1d,537082f16a315a749e705e947f2883b984:2425,836787478fce8d6276c85f719896786c662054df62e54f6381c375c85eb896cd8e0a86f9548f6cf36d8c6c38607f52c775285e7d4f1860a05fe75c24753190ae94c072b96cb96e389149670953:cbf3,4f5191c98bf153c85e7c8fc26de44e8e76c26986865e611a82064f:59de,903e9c7c61096e:1d14,96854e885a3196e84e0e5c7f79b95b878bed7fbd738957df828b90c15401904755bb5cea5fa161086b3272f180b28a:891e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3f4041424344454647494a4b4c4d4e4f505152535455565758595a5b5c5d5e#5f606162636465666768696a6b6c6d6e6f7071727374757677787a7b7c7d7e7f80,6d745bd388d598848c6b9a6d9e336e0a51:a443,57a38881539f63f48f9556ed54585706733f6e907f188fdc82d1613f6028966266f07ea68d:8ac3,94a55cb37ca4670860a6960580184e9190e75300966851418fd08574915d665597f55b55531d78386742683d54c9707e5bb08f7d518d572854b1651266828d:5e43,810f846c906d7cdf51ff85fb67a365e96fa186a48e81566a90207682707671e58d2362e952196cfd8d3c600e589e618e66fe8d60624e55b36e23672d8f678a:81828384858687888b8c8d8e8f9091929495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2#c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3,94e195f87728680569a8548b4e4d70b88bc86458658b5b857a84503a5be877bb6be18a797c986cbe76cf65a98f975d2d5c5586386808536062187ad96e5b7efd6a1f7ae05f706f335f20638c6da867564e085e108d264ed780c07634969c62db662d627e6cbc8d7571677f695146808753ec906e629854f286f08f998005951785178fd96d5973cd659f771f7504782781fb8d1e94884fa6679575b98bca9707632f9547963584b8632377415f8172f04e896014657462ef6b63653f8a:e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,8b:0001020304050608090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223#24252728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445,5e2775c790d18bc1829d679d652f5431871877e580a281026c414e4b7ec7804c76f4690d6b966267503c4f84574063076b628dbe53ea65e87eb85fd763:1ab7,81:f3f4,7f6e5e1c5cd95236667a79e97a1a8d28709975d46ede6cbb7a924e2d76c55fe0949f88777ec879cd80bf91cd4ef24f17821f54685dde6d328bcc7ca58f7480985e1a549276b15b99663c9aa473e0682a86db6731732a8b:f8db,90107af970db716e62c477a956314e3b845767f152a986c08d2e94f87b518b:464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656768696a6b6d6e6f707172737475767778797a7b7c7d7e7f80818283848586#8788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9facb1bbc7d0ea,8c:091e,4f4f6ce8795d9a7b6293722a62fd4e1378168f6c64b08d5a7bc668695e8488c55986649e58ee72b6690e95258ffd8d5857607f008c0651c6634962d95353684c74228301914c55447740707c6d4a517954a88d4459ff6ecb6dc45b5c7d2b4ed47c7d6ed35b5081ea6e0d5b579b0368d58e2a5b977efc603b7eb590b98d70594f63cd79df8db3535265cf79568bc5963b7ec494bb7e825634918967007f6a5c0a907566285de64f5067de505a4f5c57505e:a7#3$,8c:38393a3b3c3d3e3f4042434445484a4b4d4e4f5051525354565758595b5c5d5e5f60636465666768696c6d6e6f707172747576777b7c7d7e7f808183848687#888b8d8e8f90919293959697999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacad,4e:8d0c,51404e105eff53454e:15981e,9b325b6c56694e2879ba4e3f53154e47592d723b536e6c1056df80e499976bd3777e9f174e:369f,9f104e:5c6993,82885b5b556c560f4ec453:8d9da3a5ae,97658d5d53:1af5262e3e,8d5c53:6663,52:02080e2d333f404c5e615c,84af52:7d82819093,51827f544e:bbc3c9c2e8e1ebde,4f1b4ef34f:2264,4ef54f:2527092b5e67,65384f:5a5d,8c:aeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebec#edeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,8d:000102030405060708090a0b0c0d,4f:5f57323d76749189838f7e7baa7cac94e6e8eac5dae3dcd1dff8,50:294c,4ff350:2c0f2e2d,4ffe50:1c0c25287e4355484e6c7ba5a7a9bad6,510650:edece6ee,51:070b,4edd6c3d4f:5865ce,9fa06c467c74516e5dfd9ec999985181591452f9530d8a07531051eb591951554ea051564eb388:6ea4,4eb5811488d279805b3488037fb851:abb1bdbc,8d:0e0f101112131415161718191a1b1c205152575f6568696a6c6e6f717278797a7b7c7d7e7f808283868788898c8d8e8f90929395969798999a9b9c9d9ea0a1#a2a4a5a6a7a8a9aaabacadaeafb0b2b6b7b9bbbdc0c1c2c5c7c8c9cacdd0d2d3d4,51:c796a2a5,8b:a0a6a7aab4b5b7c2c3cbcfced2d3d4d6d8d9dcdfe0e4e8e9eef0f3f6f9fcff,8c:000204070c0f1112141516191b181d1f202125272a2b2e2f32333536,53:697a,96:1d2221312a3d3c4249545f676c7274888d97b0,90:979b9d99aca1b4b3b6ba,8d:d5d8d9dce0e1e2e5e6e7e9edeef0f1f2f4f6fcfeff,8e:00010203040607080b0d0e1011121315161718191a1b1c202124252627282b2d303233343637383b3c3e#3f4345464c4d4e4f505354555657585a5b5c5d5e5f60616263646567686a6b6e71,90:b8b0cfc5bed0c4c7d3e6e2dcd7dbebeffe,91:04221e23312f394346,520d594252:a2acadbe,54ff52:d0d6f0,53df71ee77cd5ef451:f5fc,9b2f53b65f01755a5def57:4ca9a1,58:7ebcc5d1,57:292c2a33392e2f5c3b4269856b867c7b686d7673ada48cb2cfa7b493a0d5d8dad9d2b8f4eff8e4dd,8e:73757778797a7b7d7e808283848688898a8b8c8d8e91929395969798999a9b9d9fa0a1a2a3a4a5a6a7a8a9aaadaeb0b1b3b4b5b6b7b8b9bbbcbdbebfc0c1c2#c3c4c5c6c7c8c9cacbcccdcfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4,58:0b0d,57:fded,58:001e194420656c81899a80,99a89f1961ff82:797d7f8f8aa8848e919799abb8beb0c8cae398b7aecbccc1a9b4a1aa9fc4cea4e1,830982:f7e4,83:0f07,82:dcf4d2d8,830c82:fbd3,83:111a061415,82:e0d5,83:1c515b5c08923c34319b5e2f4f47435f4017602d3a336665,8e:e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,8f:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223#2425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344,83:681b696c6a6d6eb078b3b4a0aa939c857cb6a97db87b989ea8babcc1,840183:e5d8,580784:180b,83:ddfdd6,84:1c381106,83:d4df,84:0f03,83:f8f9eac5c0,842683:f0e1,84:5c515a597387887a89783c4669768c8e316dc1cdd0e6bdd3cabfbae0a1b9b497e5e3,850c750d853884f085:391f3a,8f:45464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656a808c929da0a1a2a4a5a6a7aaacadaeafb2b3b4b5b7b8babbbcbfc0c3c6#c9cacbcccdcfd2d6d7dae0e1e3e7eceff1f2f4f5f6fafbfcfeff,90:07080c0e131518,85:563b,84:fffc,85:594868645e7a,77a285:43727ba4a8878f79ae9c85b9b7b0d3c1dcff,86:270529163c,5efe5f0859:3c41,803759:555a58,530f5c:22252c34,62:4c6a9fbbcadad7ee,632262f663:394b43adf6717a8eb46dac8a69aebcf2f8e0ffc4dece,645263:c6be,64:45410b1b200c26215e846d96,90:191c2324252728292a2b2c303132333437393a3d3f4043454648494a4b4c4e545556595a5c5d5e5f6061646667696a6b6c6f70717273767778797a7b7c7e81#84858687898a8c8d8e8f90929496989a9c9e9fa0a4a5a7a8a9abadb2b7bcbdbfc0,64:7ab7b899bac0d0d7e4e2,65:09252e,5f:0bd2,75195f1153:5ff1fde9e8fb,54:1216064b5253545643215759233282947771649a9b8476669dd0adc2b4d2a7a6d3d472a3d5bbbfccd9dadca9aaa4ddcfde,551b54e7552054fd551454f355:22230f11272a678fb5496d41553f503c,90:c2c3c6c8c9cbcccdd2d4d5d6d8d9dadedfe0e3e4e5e9eaeceef0f1f2f3f5f6f7f9fafbfcff,91:00010305060708090a0b0c0d0e0f1011121314151617181a1b1c#1d1f20212425262728292a2b2c2d2e30323334353637383a3b3c3d3e3f40414244,55:375675767733305c8bd283b1b988819f7ed6917bdfbdbe9499eaf7c9,561f55:d1ebecd4e6ddc4efe5f2f3cccde8f5e4,8f9456:1e080c012423,55fe56:00272d5839572c4d62595c4c548664716b7b7c8593afd4d7dde1f5ebf9ff,57:040a091c,5e:0f191411313b3c,91:454748515354555658595b5c5f606667686b6d737a7b7c808182838486888a8e8f939495969798999c9d9e9fa0a1a4a5a6a7a8a9abacb0b1b2b3b6b7b8b9bb#bcbdbebfc0c1c2c3c4c5c6c8cbd0d2d3d4d5d6d7d8d9dadbdddedfe0e1e2e3e4e5,5e:3744545b5e61,5c:8c7a8d9096889899919a9cb5a2bdacabb1a3c1b7c4d2e4cbe5,5d:020327262e241e061b583e343d6c5b6f5d6b4b4a697482999d,8c735d:b7c5,5f:73778287898c95999ca8adb5bc,88625f6172:adb0b4b7b8c3c1cecdd2e8efe9f2f4f7,730172f3730372fa91:e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,92:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324#25262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445,72fb73:1713210a1e1d152239252c3831504d57606c6f7e,821b592598e759:2402,99:636768696a6b6c74777d8084878a8d9091939495,5e:80918b96a5a0b9b5beb3,8d535e:d2d1dbe8ea,81ba5f:c4c9d6cf,60035fee60045f:e1e4fe,60:0506,5f:eaedf8,60:1935261b0f0d292b0a3f2178797b7a42,92:464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727375767778797a7b7c7d7e7f808182838485#868788898a8b8c8d8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7,60:6a7d969aad9d83928c9becbbb1ddd8c6dab4,61:20261523,60f461:000e2b4a75ac94a7b7d4f5,5fdd96b395:e9ebf1f3f5f6fcfe,96:030406080a0b0c0d0f12151617191a,4e2c723f62156c:35545c4aa38590948c6869747686a9d0d4adf7f8f1d7b2e0d6faebeeb1d3effe,92:a8a9aaabacadafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8#e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,93:00010203040506070809,6d:39270c43480704190e2b4d2e351a4f525433916f9ea05e93945c607c63,6e1a6d:c7c5de,6e0e6d:bfe0,6e116d:e6ddd9,6e166dab6e0c6dae6e:2b6e4e6bb25f865354322544dfb198e0,6f2d6e:e2a5a7bdbbb7d7b4cf8fc29f,6f:6246472415,6ef96f:2f364b742a0929898d8c78727c7ad1,93:0a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3f40414243444546474849#4a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696b,6f:c9a7b9b6c2e1eedee0ef,70:1a231b39354f5e,5b:80849593a5b8,752f9a9e64345b:e4ee,89305bf08e478b078f:b6d3d5e5eee4e9e6f3e8,90:05040b26110d162135362d2f445152506858625b,66b990:747d8288838b,5f:50575658,5c3b54ab5c:5059,5b715c:6366,7fbc5f:2a292d,82745f3c9b3b5c6e59:81838da9aaa3,93:6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab#acadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cbcccd,59:97caab9ea4d2b2afd7be,5a:0506,59dd5a0859:e3d8f9,5a:0c09323411231340674a553c6275,80ec5a:aa9b777abeebb2d2d4b8e0e3f1d6e6d8dc,5b:091716323740,5c:151c,5b:5a6573515362,9a:7577787a7f7d808185888a90929396989b9c9d9fa0a2a3a5a7,7e:9fa1a3a5a8a9,93:cecfd0d1d2d3d4d5d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,94:000102030405060708090a0b0c0d#0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e,7e:adb0bec0c1c2c9cbccd0d4d7dbe0e1e8ebeeeff1f2,7f0d7e:f6fafbfe,7f:01020307080b0c0f111217191c1b1f212223242526272a2b2c2d2f3031323335,5e7a757f5ddb753e909573:8e91aea29fcfc2d1b7b3c0c9c8e5d9,987c740a73:e9e7debaf2,74:0f2a5b262528302e2c,94:2f303132333435363738393a3b3c3d3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6c6d6e6f#707172737475767778797a7b7c7d7e7f8081828384919698c7cfd3d4dae6fb,95:1c20,74:1b1a415c575559776d7e9c8e8081878b9ea8a990a7d2ba,97:eaebec,67:4c535e4869a5876a7398a775a89ead8b777cf0,680967d8680a67:e9b0,680c67:d9b5dab3dd,680067:c3b8e2,680e67:c1fd,68:323360614e624464831d55664167403e4a4929b58f7477936bc2,696e68fc69:1f20,68f995:27333d43484b555a606e74757778797a7b7c7d7e808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa#abacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacb,692468f069:0b0157,68e369:10713960425d846b80987834cc8788ce896663799ba7bbabadd4b1c1cadf95e08dff,6a2f69ed6a:171865,69f26a:443ea0505b358e793d28587c9190a997ab,73:3752,6b:8182878492938d9a9ba1aa,8f:6b6d71727375767877797a7c7e818284878b,95:cccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7ecff,96:0713181b1e20232425262728292b2c2d2f303738393a3e41434a4e4f5152535657#58595a5c5d5e606365666b6d6e6f70717378797a7b7c7d7e7f808182838487898a,8f:8d8e8f989a,8ece62:0b171b1f222125242c,81e774:eff4ff,75:0f1113,65:34eeeff0,66:0a19,677266:031500,708566:f71d34313635,800666:5f54414f56615777848ca79dbedbdce6e9,8d:3233363b3d4045464849474d5559,89:c7cacbcccecfd0d1,72:6e9f5d666f7e7f848b8d8f92,63:0832b0,96:8c8e91929395969a9b9d9e9fa0a1a2a3a4a5a6a8a9aaabacadaeafb1b2b4b5b7b8babbbfc2c3c8cacbd0d1d3d4d6d7d8d9dadbdcdddedfe1e2e3e4e5e6e7eb#ecedeef0f1f2f4f5f8fafbfcfdff,97:0203050a0b0c10111214151718191a1b1d1f20,64:3fd8,80046b:eaf3fdf5f9,6c:0507060d1518191a2129242a32,65:35556b,72:4d525630,8662521680:9f9c93bc,670a80:bdb1abadb4b7e7e8e9eadbc2c4d9cdd7,671080:ddebf1f4ed,81:0d0e,80:f2fc,671581128c5a81:361e2c1832484c5374595a7160697c7d6d67,584d5ab581:888291,6ed581:a3aacc,672681:cabb,97:2122232425262728292b2c2e2f3133343536373a3b3c3d3f404142434445464748494a4b4c4d4e4f5051545557585a5c5d5f63646667686a6b6c6d6e6f7071#72757778797a7b7d7e7f8081828384868788898a8c8e8f9093959697999a9b9c9d,81:c1a6,6b:243739434659,98:d1d2d3d5d9da,6bb35f406bc289f365909f5165:93bcc6c4c3ccced2d6,70:809c969dbbc0b7abb1e8ca,71:1013162f31735c6845724a787a98b3b5a8a0e0d4e7f9,72:1d28,706c71:1866b9,62:3e3d434849,79:3b4046495b5c535a6257606f677a858a9aa7b3,5f:d1d0,97:9e9fa1a2a4a5a6a7a8a9aaacaeb0b1b3b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3#e4e5e8eeeff0f1f2f4f7f8f9fafbfcfdfeff,98:000102030405060708090a0b0c0d0e,60:3c5d5a67415963ab,61:060d5da99dcbd1,620680:807f,6c:93f6,6dfc77:f6f8,78:0009171811,65ab78:2d1c1d393a3b1f3c252c23294e6d56572650474c6a9b939a879ca1a3b2b9a5d4d9c9ecf2,790578f479:13241e34,9f9b9e:f9fbfc,76f177:040d,76f977:07081a22192d263538505147435a68,98:0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d#4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e,77:62657f8d7d808c919fa0b0b5bd,75:3a404e4b485b727983,7f:58615f,8a487f:68747179817e,76:cde5,883294:8586878b8a8c8d8f909497959a9b9ca3a4abaaadacafb0b2b4b6b7b8b9babcbdbfc4c8c9cacbcccdced0d1d2d5d6d7d9d8dbdedfe0e2e4e5e7e8ea,98:6f70717273748b8e929599a3a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcfd0d4d6d7dbdcdde0e1e2e3e4#e5e6e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,99:0001020304050607,94:e9ebeeeff3f4f5f7f9fcfdff,95:03020607090a0d0e0f1213141516181b1d1e1f222a2b292c3132343637383c3e3f4235444546494c4e4f525354565758595b5e5f5d61626465666768696a6b6c6f7172733a,77:e7ec,96c979:d5ede3eb,7a065d477a:03021e14,99:08090a0b0c0e0f1112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2f303132333435363738393a3b3c3d3e3f40414243444546474849#4a4b4c4d4e4f50515253565758595a5b5c5d5e5f60616264667378797b7e828389,7a:393751,9ecf99a57a7076:888e9399a4,74:dee0,752c9e:202228292a2b2c3231363837393a3e414244464748494b4c4e5155575a5b5c5e63666768696a6b6c716d73,75:929496a09daca3b3b4b8c4b1b0c3c2d6cde3e8e6e4ebe7,760375:f1fcff,76:1000050c170a25181519,99:8c8e9a9b9c9d9e9fa0a1a2a3a4a6a7a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8#d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9,76:1b3c2220402d303f35433e334d5e545c566b6f,7fca7a:e6787980868895a6a0aca8adb3,88:6469727d7f82a2c6b7bcc9e2cee3e5f1,891a88:fce8fef0,89:2119131b0a342b3641667b,758b80e576:b2b4,77dc80:1214161c20222526272928310b3543464d526971,898398:788083,99:fafbfcfdfeff,9a:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738#393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556575859,98:898c8d8f949a9b9e9fa1a2a5a6,86:4d546c6e7f7a7c7ba88d8bac9da7a3aa93a9b6c4b5ceb0bab1afc9cfb4e9f1f2edf3d0,871386:def4dfd8d1,87:0307,86f887:080a0d09233b1e252e1a3e48343129373f82227d7e7b60704c6e8b53637c64596593afa8d2,9a:5a5b5c5d5e5f606162636465666768696a6b7283898d8e949599a6a9aaabacadaeafb2b3b4b5b9bbbdbebfc3c4c6c7c8c9cacdcecfd0d2d4d5d6d7d9dadbdc#dddee0e2e3e4e5e7e8e9eaeceef0f1f2f3f4f5f6f7f8fafcfdfeff,9b:000102040506,87:c68885ad9783abe5acb5b3cbd3bdd1c0cadbeae0ee,88:1613,87fe88:0a1b21393c,7f:36424445,82107a:fafd,7b:080304150a2b0f47382a192e31202524333e1e585a45754c5d606e7b62727190a6a7b8ac9da885aa9ca2abb4d1c1ccdddae5e6ea,7c0c7b:fefc,7c:0f160b,9b:07090a0b0c0d0e1011121415161718191a1b1c1d1e2021222425262728292a2b2c2d2e3031333435363738393a3d3e3f40464a4b4c4e50525355565758595a#5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b,7c:1f2a26384140,81fe82:010204,81ec884482:2122232d2f282b383b33343e44494b4f5a5f68,88:7e8588d8df,895e7f:9d9fa7afb0b2,7c7c65497c:919d9c9ea2b2bcbdc1c7cccdc8c5d7e8,826e66a87f:bfced5e5e1e6e9eef3,7cf87d:77a6ae,7e:479b,9e:b8b4,8d:73849491b1676d,8c:4749,91:4a504e4f64,9b:7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9ba#bbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb,91:626170696f7d7e7274798c85908d91a2a3aaadaeafb5b4ba,8c559e7e8d:b8eb,8e:055969,8d:b5bfbcbac4d6d7dadececfdbc6ecf7f8e3f9fbe4,8e098dfd8e:141d1f2c2e232f3a4039353d3149414251524a70767c6f74858f94909c9e,8c:78828a859894,659b89:d6dedadc,9b:dcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,9c:000102030405060708090a0b0c0d0e0f101112131415161718191a#1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b,89:e5ebef,8a3e8b26975396:e9f3ef,97:0601080f0e2a2d303e,9f:808385868788898a8c,9efe9f:0b0d,96:b9bcbdced2,77bf96e092:8eaec8,93:3e6aca8f,94:3e6b,9c:7f8285868788,7a239c:8b8e90919294959a9b9e9fa0a1a2a3a5a6a7a8a9abadaeb0b1b2b3b4b5b6b7babbbcbdc4c5c6c7cacb3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a#7b7d7e808384898a8c8f93969798999daaacafb9bebfc0c1c2c8c9d1d2dadbe0e1cccdcecfd0d3d4d5d7d8d9dcdddfe2,97:7c85919294afaba3b2b4,9a:b1b0b7,9e589a:b6babcc1c0c5c2cbccd1,9b:45434749484d51,98e899:0d2e5554,9a:dfe1e6efebfbedf9,9b:080f131f23,9e:bdbe,7e3b9e:8287888b92,93d69e:9d9fdbdcdde0dfe2e9e7e5eaef,9f:222c2f39373d3e44,9c:e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,9d:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021#22232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142#92$434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081#82838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2#92$a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1#e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff,9e:000102#92$030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e24272e30343b3c404d5052535456595d5f606162656e6f727475767778797a7b7c7d80#8183848586898a8c8d8e8f90919495969798999a9b9c9ea0a1a2a3a4a5a7a8a9aa#92$abacadaeafb0b1b2b3b5b6b7b9babcbfc0c1c2c3c5c6c7c8cacbccd0d2d3d5d6d7d9dadee1e3e4e6e8ebecedeef0f1f2f3f4f5f6f7f8fafdff,9f:000102030405#060708090a0c0f1112141516181a1b1c1d1e1f21232425262728292a2b2d2e3031#92$3233343536383a3c3f4041424345464748494a4b4c4d4e4f52535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778#797a7b7c7d7e81828d8e8f9091929394959697989c9d9ea1a2a3a4a5,f9:2c7995e7f1#92$,fa:0c0d0e0f111314181f20212324272829,e8:15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243#4445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364'), - U2Ghash={}, - G2Uhash={}; - !function(data){ - var k=0; - data=data.match(/..../g); - for(var i=0x81;i<=0xfe;i++){ - for(var j=0x40;j<=0xFE;j++){ - U2Ghash[data[k++]]=('%'+i.toString(16)+'%'+j.toString(16)) - .toUpperCase(); - } - } - for(var key in U2Ghash){ - G2Uhash[U2Ghash[key]]=key; - } - }(data); - function isAscii(unicode) { - return ((unicode == 0x20AC) || (unicode <= 0x007F && unicode >= 0x0000)); - } - return{ - encode:function(str){ - return str.replace(/./g,function(a){ - var code=a.charCodeAt(0); - if(isAscii(code)){ - return encodeURIComponent(a); - }else{ - var key=code.toString(16); - if(key.length!=4)key=('000'+key).match(/....$/)[0]; - return U2Ghash[key]||a; - } - }); - }, - decode:function(str){ - return str.replace(/%[0-9A-F]{2}%[0-9A-F]{2}/g,function(a){ - if(a in G2Uhash){ - return String.fromCharCode('0x'+G2Uhash[a]); - }else{ - return a; - } - }).replace(/%[\w]{2}/g,function(a){ - return decodeURIComponent(a); - - }); - } - }; -} \ No newline at end of file diff --git a/lib/mod.js b/lib/mod.js deleted file mode 100644 index 719f2b8f..00000000 --- a/lib/mod.js +++ /dev/null @@ -1,138 +0,0 @@ -const peq = new Uint32Array(0x10000); -const myers_32 = (a, b) => { - const n = a.length; - const m = b.length; - const lst = 1 << (n - 1); - let pv = -1; - let mv = 0; - let sc = n; - let i = n; - while (i--) { - peq[a.charCodeAt(i)] |= 1 << i; - } - for (i = 0; i < m; i++) { - let eq = peq[b.charCodeAt(i)]; - const xv = eq | mv; - eq |= ((eq & pv) + pv) ^ pv; - mv |= ~(eq | pv); - pv &= eq; - if (mv & lst) { - sc++; - } - if (pv & lst) { - sc--; - } - mv = (mv << 1) | 1; - pv = (pv << 1) | ~(xv | mv); - mv &= xv; - } - i = n; - while (i--) { - peq[a.charCodeAt(i)] = 0; - } - return sc; -}; -const myers_x = (b, a) => { - const n = a.length; - const m = b.length; - const mhc = []; - const phc = []; - const hsize = Math.ceil(n / 32); - const vsize = Math.ceil(m / 32); - for (let i = 0; i < hsize; i++) { - phc[i] = -1; - mhc[i] = 0; - } - let j = 0; - for (; j < vsize - 1; j++) { - let mv = 0; - let pv = -1; - const start = j * 32; - const vlen = Math.min(32, m) + start; - for (let k = start; k < vlen; k++) { - peq[b.charCodeAt(k)] |= 1 << k; - } - for (let i = 0; i < n; i++) { - const eq = peq[a.charCodeAt(i)]; - const pb = (phc[(i / 32) | 0] >>> i) & 1; - const mb = (mhc[(i / 32) | 0] >>> i) & 1; - const xv = eq | mv; - const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; - let ph = mv | ~(xh | pv); - let mh = pv & xh; - if ((ph >>> 31) ^ pb) { - phc[(i / 32) | 0] ^= 1 << i; - } - if ((mh >>> 31) ^ mb) { - mhc[(i / 32) | 0] ^= 1 << i; - } - ph = (ph << 1) | pb; - mh = (mh << 1) | mb; - pv = mh | ~(xv | ph); - mv = ph & xv; - } - for (let k = start; k < vlen; k++) { - peq[b.charCodeAt(k)] = 0; - } - } - let mv = 0; - let pv = -1; - const start = j * 32; - const vlen = Math.min(32, m - start) + start; - for (let k = start; k < vlen; k++) { - peq[b.charCodeAt(k)] |= 1 << k; - } - let score = m; - for (let i = 0; i < n; i++) { - const eq = peq[a.charCodeAt(i)]; - const pb = (phc[(i / 32) | 0] >>> i) & 1; - const mb = (mhc[(i / 32) | 0] >>> i) & 1; - const xv = eq | mv; - const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb; - let ph = mv | ~(xh | pv); - let mh = pv & xh; - score += (ph >>> (m - 1)) & 1; - score -= (mh >>> (m - 1)) & 1; - if ((ph >>> 31) ^ pb) { - phc[(i / 32) | 0] ^= 1 << i; - } - if ((mh >>> 31) ^ mb) { - mhc[(i / 32) | 0] ^= 1 << i; - } - ph = (ph << 1) | pb; - mh = (mh << 1) | mb; - pv = mh | ~(xv | ph); - mv = ph & xv; - } - for (let k = start; k < vlen; k++) { - peq[b.charCodeAt(k)] = 0; - } - return score; -}; -const distance = (a, b) => { - if (a.length < b.length) { - const tmp = b; - b = a; - a = tmp; - } - if (b.length === 0) { - return a.length; - } - if (a.length <= 32) { - return myers_32(a, b); - } - return myers_x(a, b); -}; -const closest = (str, arr) => { - let min_distance = Infinity; - let min_index = 0; - for (let i = 0; i < arr.length; i++) { - const dist = distance(str, arr[i]); - if (dist < min_distance) { - min_distance = dist; - min_index = i; - } - } - return arr[min_index]; -}; -export { closest, distance }; diff --git a/lib/pre.js b/lib/pre.js deleted file mode 100644 index fb957f38..00000000 --- a/lib/pre.js +++ /dev/null @@ -1,267 +0,0 @@ -var VODS = []; -var $ = {}; - if (!String.prototype.includes) { - String.prototype.includes = function (search, start) { - - if (typeof start !== 'number') { - start = 0; - } - - if (start + search.length > this.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) {//this是空或者未定义,抛出错误 - throw new TypeError('"this" is null or not defined'); - } - - var o = Object(this);//将this转变成对象 - var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0 - - if (len === 0) {//length为0直接返回false未找到目标值 - return false; - } - - var n = fromIndex | 0;//查找起始索引 - var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);//计算正确起始索引,因为有可能是负值 - - while (k < len) {//从起始索引处开始循环 - if (o[k] === searchElement) {//如果某一位置与寻找目标相等,返回true,找到了 - return true; - } - k++; - } - return false;//未找到,返回false - } - }); - } -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (prefix){ - return this.slice(0, prefix.length) === prefix; - }; -} -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function(suffix) { - return this.indexOf(suffix, this.length - suffix.length) !== -1; - }; -} - -Object.assign = function () { - var target = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; -}; -Object.prototype.myValues=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; -} -if (typeof Object.prototype.values != 'function') { - Object.prototype.values=function(obj){ - if(obj ==null) { - throw new TypeError("Cannot convert undefined or null to object"); - } - var res=[] - for(var k in obj){ - if(obj.hasOwnProperty(k)){//需判断是否是本身的属性 - res.push(obj[k]); - } - } - return res; -} -} - -Array.prototype.join = function (emoji) { - // emoji = emoji||','; - emoji = emoji||''; - let self = this; - let str = ""; - let i = 0; - if (!Array.isArray(self)) {throw String(self)+'is not Array'} - if(self.length===0){return ''} - if (self.length === 1){return String(self[0])} - i = 1; - str = this[0]; - for (; i < self.length; i++) { - str += String(emoji)+String(self[i]); - } - return str; -}; -Array.prototype.append = Array.prototype.push; -String.prototype.strip = String.prototype.trim; -function 是否正版(vipUrl){ - let flag = new RegExp('qq\.com|iqiyi\.com|youku\.com|mgtv\.com|bilibili\.com|sohu\.com|ixigua\.com|pptv\.com|miguvideo\.com|le\.com|1905\.com|fun\.tv'); - return flag.test(vipUrl); -} -function urlDeal(vipUrl){ - if(!vipUrl){ - return '' - } - if(!是否正版(vipUrl)){ - return vipUrl - } - if(!/miguvideo/.test(vipUrl)){ - vipUrl=vipUrl.split('#')[0].split('?')[0]; - } - return vipUrl -} -function setResult(d){ - if(!Array.isArray(d)){ - return [] - } - d.forEach(function (it){ - let obj = { - vod_id:it.url||'', - vod_name: it.title||'', - vod_remarks: it.desc||'', - vod_content: it.content||'', - vod_pic: it.pic_url||it.img||'', - }; - let keys = Object.keys(it); - if(keys.includes('tname')){ - obj.type_name = it.tname||''; - } - if(keys.includes('tid')){ - obj.type_id = it.tid||''; - } - if(keys.includes('year')){ - obj.vod_year = it.year||''; - } - if(keys.includes('actor')){ - obj.vod_actor = it.actor||''; - } - if(keys.includes('director')){ - obj.vod_director = it.director||''; - } - if(keys.includes('area')){ - obj.vod_area = it.area||''; - } - VODS.push(obj); - }); - return VODS -} -function setResult2(res){ - VODS = res.list||[]; - return VODS -} -function setHomeResult(res){ - if(!res||typeof(res)!=='object'){ - return [] - } - return setResult(res.list); -} -// 千万不要用for in 推荐 forEach (for in 会打乱顺序) -//猫函数 -function maoss(jxurl, ref, key) { - eval(getCryptoJS()); - try { - var getVideoInfo = function (text) { - return CryptoJS.AES.decrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); - }; - var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key; - if (ref) { - var html = request(jxurl, { - headers: { - 'Referer': ref - } - }); - } else { - var html = request(jxurl); - } - // print(html); - if (html.indexOf('&btwaf=') != -1) { - html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], { - headers: { - 'Referer': ref - } - }) - } - var token_iv = html.split('_token = "')[1].split('"')[0]; - var key = CryptoJS.enc.Utf8.parse(token_key); - var iv = CryptoJS.enc.Utf8.parse(token_iv); - // log("iv:"+iv); - // log(html); - // print(key); - // print(iv); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - // config.url = config.url.replace(/,/g,''); - // print(config.url); - if (!config.url.startsWith('http')) { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - config.url = CryptoJS.AES.decrypt(config.url, key, { - iv: iv, - padding: CryptoJS.pad.Pkcs7 - }).toString(CryptoJS.enc.Utf8) - } - return config.url; - } catch (e) { - return ''; - } -} - -function request(url,obj){ - // obj = obj||{'user-agent': MOBILE_UA}; - let new_obj; - if(typeof(fetch_params)!=='undefined'){ - new_obj = obj?Object.assign(fetch_params,obj):fetch_params; - }else{ - new_obj = obj||{} - } - if(!new_obj||!new_obj.headers){ - new_obj.headers = {}; - } - if(!new_obj.headers['User-Agent']&&!new_obj.headers['user-agent']){ - new_obj.headers['User-Agent'] = MOBILE_UA; - } - // delete new_obj.headers['Referer']; - // print(obj); - // print(new_obj); - if(typeof(fetch)!==undefined){ - let html = fetch(url,new_obj); - if (/\?btwaf=/.test(html)) {//宝塔验证 - url=url.split('#')[0]+'?btwaf'+html.match(/btwaf(.*?)\"/)[1]; - log("宝塔验证跳转到:"+url); - html = fetch(url, new_obj); - } - return html - } - return '' -} - -function rc(url){// 系统已经有require方法了,再覆盖的话无法操作了 - res = eval(requireObj(url)); - // print(res); - return res; - // return eval.call(null, requireObj(url)); -} - -$.require = rc; - -function urlencode (str) { - str = (str + '').toString(); - - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28'). - replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'); -} \ No newline at end of file diff --git a/lib/sortName.js b/lib/sortName.js deleted file mode 100644 index b072933f..00000000 --- a/lib/sortName.js +++ /dev/null @@ -1,178 +0,0 @@ -var strChineseFirstPY = "YDYQSXMWZSSXJBYMGCCZQPSSQBYCDSCDQLDYLYBSSJGYZZJJFKCCLZDHWDWZJLJPFYYNWJJTMYHZWZHFLZPPQHGSCYYYNJQYXXGJHHSDSJNKKTMOMLCRXYPSNQSECCQZGGLLYJLMYZZSECYKYYHQWJSSGGYXYZYJWWKDJHYCHMYXJTLXJYQBYXZLDWRDJRWYSRLDZJPCBZJJBRCFTLECZSTZFXXZHTRQHYBDLYCZSSYMMRFMYQZPWWJJYFCRWFDFZQPYDDWYXKYJAWJFFXYPSFTZYHHYZYSWCJYXSCLCXXWZZXNBGNNXBXLZSZSBSGPYSYZDHMDZBQBZCWDZZYYTZHBTSYYBZGNTNXQYWQSKBPHHLXGYBFMJEBJHHGQTJCYSXSTKZHLYCKGLYSMZXYALMELDCCXGZYRJXSDLTYZCQKCNNJWHJTZZCQLJSTSTBNXBTYXCEQXGKWJYFLZQLYHYXSPSFXLMPBYSXXXYDJCZYLLLSJXFHJXPJBTFFYABYXBHZZBJYZLWLCZGGBTSSMDTJZXPTHYQTGLJSCQFZKJZJQNLZWLSLHDZBWJNCJZYZSQQYCQYRZCJJWYBRTWPYFTWEXCSKDZCTBZHYZZYYJXZCFFZZMJYXXSDZZOTTBZLQWFCKSZSXFYRLNYJMBDTHJXSQQCCSBXYYTSYFBXDZTGBCNSLCYZZPSAZYZZSCJCSHZQYDXLBPJLLMQXTYDZXSQJTZPXLCGLQTZWJBHCTSYJSFXYEJJTLBGXSXJMYJQQPFZASYJNTYDJXKJCDJSZCBARTDCLYJQMWNQNCLLLKBYBZZSYHQQLTWLCCXTXLLZNTYLNEWYZYXCZXXGRKRMTCNDNJTSYYSSDQDGHSDBJGHRWRQLYBGLXHLGTGXBQJDZPYJSJYJCTMRNYMGRZJCZGJMZMGXMPRYXKJNYMSGMZJYMKMFXMLDTGFBHCJHKYLPFMDXLQJJSMTQGZSJLQDLDGJYCALCMZCSDJLLNXDJFFFFJCZFMZFFPFKHKGDPSXKTACJDHHZDDCRRCFQYJKQCCWJDXHWJLYLLZGCFCQDSMLZPBJJPLSBCJGGDCKKDEZSQCCKJGCGKDJTJDLZYCXKLQSCGJCLTFPCQCZGWPJDQYZJJBYJHSJDZWGFSJGZKQCCZLLPSPKJGQJHZZLJPLGJGJJTHJJYJZCZMLZLYQBGJWMLJKXZDZNJQSYZMLJLLJKYWXMKJLHSKJGBMCLYYMKXJQLBMLLKMDXXKWYXYSLMLPSJQQJQXYXFJTJDXMXXLLCXQBSYJBGWYMBGGBCYXPJYGPEPFGDJGBHBNSQJYZJKJKHXQFGQZKFHYGKHDKLLSDJQXPQYKYBNQSXQNSZSWHBSXWHXWBZZXDMNSJBSBKBBZKLYLXGWXDRWYQZMYWSJQLCJXXJXKJEQXSCYETLZHLYYYSDZPAQYZCMTLSHTZCFYZYXYLJSDCJQAGYSLCQLYYYSHMRQQKLDXZSCSSSYDYCJYSFSJBFRSSZQSBXXPXJYSDRCKGJLGDKZJZBDKTCSYQPYHSTCLDJDHMXMCGXYZHJDDTMHLTXZXYLYMOHYJCLTYFBQQXPFBDFHHTKSQHZYYWCNXXCRWHOWGYJLEGWDQCWGFJYCSNTMYTOLBYGWQWESJPWNMLRYDZSZTXYQPZGCWXHNGPYXSHMYQJXZTDPPBFYHZHTJYFDZWKGKZBLDNTSXHQEEGZZYLZMMZYJZGXZXKHKSTXNXXWYLYAPSTHXDWHZYMPXAGKYDXBHNHXKDPJNMYHYLPMGOCSLNZHKXXLPZZLBMLSFBHHGYGYYGGBHSCYAQTYWLXTZQCEZYDQDQMMHTKLLSZHLSJZWFYHQSWSCWLQAZYNYTLSXTHAZNKZZSZZLAXXZWWCTGQQTDDYZTCCHYQZFLXPSLZYGPZSZNGLNDQTBDLXGTCTAJDKYWNSYZLJHHZZCWNYYZYWMHYCHHYXHJKZWSXHZYXLYSKQYSPSLYZWMYPPKBYGLKZHTYXAXQSYSHXASMCHKDSCRSWJPWXSGZJLWWSCHSJHSQNHCSEGNDAQTBAALZZMSSTDQJCJKTSCJAXPLGGXHHGXXZCXPDMMHLDGTYBYSJMXHMRCPXXJZCKZXSHMLQXXTTHXWZFKHCCZDYTCJYXQHLXDHYPJQXYLSYYDZOZJNYXQEZYSQYAYXWYPDGXDDXSPPYZNDLTWRHXYDXZZJHTCXMCZLHPYYYYMHZLLHNXMYLLLMDCPPXHMXDKYCYRDLTXJCHHZZXZLCCLYLNZSHZJZZLNNRLWHYQSNJHXYNTTTKYJPYCHHYEGKCTTWLGQRLGGTGTYGYHPYHYLQYQGCWYQKPYYYTTTTLHYHLLTYTTSPLKYZXGZWGPYDSSZZDQXSKCQNMJJZZBXYQMJRTFFBTKHZKBXLJJKDXJTLBWFZPPTKQTZTGPDGNTPJYFALQMKGXBDCLZFHZCLLLLADPMXDJHLCCLGYHDZFGYDDGCYYFGYDXKSSEBDHYKDKDKHNAXXYBPBYYHXZQGAFFQYJXDMLJCSQZLLPCHBSXGJYNDYBYQSPZWJLZKSDDTACTBXZDYZYPJZQSJNKKTKNJDJGYYPGTLFYQKASDNTCYHBLWDZHBBYDWJRYGKZYHEYYFJMSDTYFZJJHGCXPLXHLDWXXJKYTCYKSSSMTWCTTQZLPBSZDZWZXGZAGYKTYWXLHLSPBCLLOQMMZSSLCMBJCSZZKYDCZJGQQDSMCYTZQQLWZQZXSSFPTTFQMDDZDSHDTDWFHTDYZJYQJQKYPBDJYYXTLJHDRQXXXHAYDHRJLKLYTWHLLRLLRCXYLBWSRSZZSYMKZZHHKYHXKSMDSYDYCJPBZBSQLFCXXXNXKXWYWSDZYQOGGQMMYHCDZTTFJYYBGSTTTYBYKJDHKYXBELHTYPJQNFXFDYKZHQKZBYJTZBXHFDXKDASWTAWAJLDYJSFHBLDNNTNQJTJNCHXFJSRFWHZFMDRYJYJWZPDJKZYJYMPCYZNYNXFBYTFYFWYGDBNZZZDNYTXZEMMQBSQEHXFZMBMFLZZSRXYMJGSXWZJSPRYDJSJGXHJJGLJJYNZZJXHGXKYMLPYYYCXYTWQZSWHWLYRJLPXSLSXMFSWWKLCTNXNYNPSJSZHDZEPTXMYYWXYYSYWLXJQZQXZDCLEEELMCPJPCLWBXSQHFWWTFFJTNQJHJQDXHWLBYZNFJLALKYYJLDXHHYCSTYYWNRJYXYWTRMDRQHWQCMFJDYZMHMYYXJWMYZQZXTLMRSPWWCHAQBXYGZYPXYYRRCLMPYMGKSJSZYSRMYJSNXTPLNBAPPYPYLXYYZKYNLDZYJZCZNNLMZHHARQMPGWQTZMXXMLLHGDZXYHXKYXYCJMFFYYHJFSBSSQLXXNDYCANNMTCJCYPRRNYTYQNYYMBMSXNDLYLYSLJRLXYSXQMLLYZLZJJJKYZZCSFBZXXMSTBJGNXYZHLXNMCWSCYZYFZLXBRNNNYLBNRTGZQYSATSWRYHYJZMZDHZGZDWYBSSCSKXSYHYTXXGCQGXZZSHYXJSCRHMKKBXCZJYJYMKQHZJFNBHMQHYSNJNZYBKNQMCLGQHWLZNZSWXKHLJHYYBQLBFCDSXDLDSPFZPSKJYZWZXZDDXJSMMEGJSCSSMGCLXXKYYYLNYPWWWGYDKZJGGGZGGSYCKNJWNJPCXBJJTQTJWDSSPJXZXNZXUMELPXFSXTLLXCLJXJJLJZXCTPSWXLYDHLYQRWHSYCSQYYBYAYWJJJQFWQCQQCJQGXALDBZZYJGKGXPLTZYFXJLTPADKYQHPMATLCPDCKBMTXYBHKLENXDLEEGQDYMSAWHZMLJTWYGXLYQZLJEEYYBQQFFNLYXRDSCTGJGXYYNKLLYQKCCTLHJLQMKKZGCYYGLLLJDZGYDHZWXPYSJBZKDZGYZZHYWYFQYTYZSZYEZZLYMHJJHTSMQWYZLKYYWZCSRKQYTLTDXWCTYJKLWSQZWBDCQYNCJSRSZJLKCDCDTLZZZACQQZZDDXYPLXZBQJYLZLLLQDDZQJYJYJZYXNYYYNYJXKXDAZWYRDLJYYYRJLXLLDYXJCYWYWNQCCLDDNYYYNYCKCZHXXCCLGZQJGKWPPCQQJYSBZZXYJSQPXJPZBSBDSFNSFPZXHDWZTDWPPTFLZZBZDMYYPQJRSDZSQZSQXBDGCPZSWDWCSQZGMDHZXMWWFYBPDGPHTMJTHZSMMBGZMBZJCFZWFZBBZMQCFMBDMCJXLGPNJBBXGYHYYJGPTZGZMQBQTCGYXJXLWZKYDPDYMGCFTPFXYZTZXDZXTGKMTYBBCLBJASKYTSSQYYMSZXFJEWLXLLSZBQJJJAKLYLXLYCCTSXMCWFKKKBSXLLLLJYXTYLTJYYTDPJHNHNNKBYQNFQYYZBYYESSESSGDYHFHWTCJBSDZZTFDMXHCNJZYMQWSRYJDZJQPDQBBSTJGGFBKJBXTGQHNGWJXJGDLLTHZHHYYYYYYSXWTYYYCCBDBPYPZYCCZYJPZYWCBDLFWZCWJDXXHYHLHWZZXJTCZLCDPXUJCZZZLYXJJTXPHFXWPYWXZPTDZZBDZCYHJHMLXBQXSBYLRDTGJRRCTTTHYTCZWMXFYTWWZCWJWXJYWCSKYBZSCCTZQNHXNWXXKHKFHTSWOCCJYBCMPZZYKBNNZPBZHHZDLSYDDYTYFJPXYNGFXBYQXCBHXCPSXTYZDMKYSNXSXLHKMZXLYHDHKWHXXSSKQYHHCJYXGLHZXCSNHEKDTGZXQYPKDHEXTYKCNYMYYYPKQYYYKXZLTHJQTBYQHXBMYHSQCKWWYLLHCYYLNNEQXQWMCFBDCCMLJGGXDQKTLXKGNQCDGZJWYJJLYHHQTTTNWCHMXCXWHWSZJYDJCCDBQCDGDNYXZTHCQRXCBHZTQCBXWGQWYYBXHMBYMYQTYEXMQKYAQYRGYZSLFYKKQHYSSQYSHJGJCNXKZYCXSBXYXHYYLSTYCXQTHYSMGSCPMMGCCCCCMTZTASMGQZJHKLOSQYLSWTMXSYQKDZLJQQYPLSYCZTCQQPBBQJZCLPKHQZYYXXDTDDTSJCXFFLLCHQXMJLWCJCXTSPYCXNDTJSHJWXDQQJSKXYAMYLSJHMLALYKXCYYDMNMDQMXMCZNNCYBZKKYFLMCHCMLHXRCJJHSYLNMTJZGZGYWJXSRXCWJGJQHQZDQJDCJJZKJKGDZQGJJYJYLXZXXCDQHHHEYTMHLFSBDJSYYSHFYSTCZQLPBDRFRZTZYKYWHSZYQKWDQZRKMSYNBCRXQBJYFAZPZZEDZCJYWBCJWHYJBQSZYWRYSZPTDKZPFPBNZTKLQYHBBZPNPPTYZZYBQNYDCPJMMCYCQMCYFZZDCMNLFPBPLNGQJTBTTNJZPZBBZNJKLJQYLNBZQHKSJZNGGQSZZKYXSHPZSNBCGZKDDZQANZHJKDRTLZLSWJLJZLYWTJNDJZJHXYAYNCBGTZCSSQMNJPJYTYSWXZFKWJQTKHTZPLBHSNJZSYZBWZZZZLSYLSBJHDWWQPSLMMFBJDWAQYZTCJTBNNWZXQXCDSLQGDSDPDZHJTQQPSWLYYJZLGYXYZLCTCBJTKTYCZJTQKBSJLGMGZDMCSGPYNJZYQYYKNXRPWSZXMTNCSZZYXYBYHYZAXYWQCJTLLCKJJTJHGDXDXYQYZZBYWDLWQCGLZGJGQRQZCZSSBCRPCSKYDZNXJSQGXSSJMYDNSTZTPBDLTKZWXQWQTZEXNQCZGWEZKSSBYBRTSSSLCCGBPSZQSZLCCGLLLZXHZQTHCZMQGYZQZNMCOCSZJMMZSQPJYGQLJYJPPLDXRGZYXCCSXHSHGTZNLZWZKJCXTCFCJXLBMQBCZZWPQDNHXLJCTHYZLGYLNLSZZPCXDSCQQHJQKSXZPBAJYEMSMJTZDXLCJYRYYNWJBNGZZTMJXLTBSLYRZPYLSSCNXPHLLHYLLQQZQLXYMRSYCXZLMMCZLTZSDWTJJLLNZGGQXPFSKYGYGHBFZPDKMWGHCXMSGDXJMCJZDYCABXJDLNBCDQYGSKYDQTXDJJYXMSZQAZDZFSLQXYJSJZYLBTXXWXQQZBJZUFBBLYLWDSLJHXJYZJWTDJCZFQZQZZDZSXZZQLZCDZFJHYSPYMPQZMLPPLFFXJJNZZYLSJEYQZFPFZKSYWJJJHRDJZZXTXXGLGHYDXCSKYSWMMZCWYBAZBJKSHFHJCXMHFQHYXXYZFTSJYZFXYXPZLCHMZMBXHZZSXYFYMNCWDABAZLXKTCSHHXKXJJZJSTHYGXSXYYHHHJWXKZXSSBZZWHHHCWTZZZPJXSNXQQJGZYZYWLLCWXZFXXYXYHXMKYYSWSQMNLNAYCYSPMJKHWCQHYLAJJMZXHMMCNZHBHXCLXTJPLTXYJHDYYLTTXFSZHYXXSJBJYAYRSMXYPLCKDUYHLXRLNLLSTYZYYQYGYHHSCCSMZCTZQXKYQFPYYRPFFLKQUNTSZLLZMWWTCQQYZWTLLMLMPWMBZSSTZRBPDDTLQJJBXZCSRZQQYGWCSXFWZLXCCRSZDZMCYGGDZQSGTJSWLJMYMMZYHFBJDGYXCCPSHXNZCSBSJYJGJMPPWAFFYFNXHYZXZYLREMZGZCYZSSZDLLJCSQFNXZKPTXZGXJJGFMYYYSNBTYLBNLHPFZDCYFBMGQRRSSSZXYSGTZRNYDZZCDGPJAFJFZKNZBLCZSZPSGCYCJSZLMLRSZBZZLDLSLLYSXSQZQLYXZLSKKBRXBRBZCYCXZZZEEYFGKLZLYYHGZSGZLFJHGTGWKRAAJYZKZQTSSHJJXDCYZUYJLZYRZDQQHGJZXSSZBYKJPBFRTJXLLFQWJHYLQTYMBLPZDXTZYGBDHZZRBGXHWNJTJXLKSCFSMWLSDQYSJTXKZSCFWJLBXFTZLLJZLLQBLSQMQQCGCZFPBPHZCZJLPYYGGDTGWDCFCZQYYYQYSSCLXZSKLZZZGFFCQNWGLHQYZJJCZLQZZYJPJZZBPDCCMHJGXDQDGDLZQMFGPSYTSDYFWWDJZJYSXYYCZCYHZWPBYKXRYLYBHKJKSFXTZJMMCKHLLTNYYMSYXYZPYJQYCSYCWMTJJKQYRHLLQXPSGTLYYCLJSCPXJYZFNMLRGJJTYZBXYZMSJYJHHFZQMSYXRSZCWTLRTQZSSTKXGQKGSPTGCZNJSJCQCXHMXGGZTQYDJKZDLBZSXJLHYQGGGTHQSZPYHJHHGYYGKGGCWJZZYLCZLXQSFTGZSLLLMLJSKCTBLLZZSZMMNYTPZSXQHJCJYQXYZXZQZCPSHKZZYSXCDFGMWQRLLQXRFZTLYSTCTMJCXJJXHJNXTNRZTZFQYHQGLLGCXSZSJDJLJCYDSJTLNYXHSZXCGJZYQPYLFHDJSBPCCZHJJJQZJQDYBSSLLCMYTTMQTBHJQNNYGKYRQYQMZGCJKPDCGMYZHQLLSLLCLMHOLZGDYYFZSLJCQZLYLZQJESHNYLLJXGJXLYSYYYXNBZLJSSZCQQCJYLLZLTJYLLZLLBNYLGQCHXYYXOXCXQKYJXXXYKLXSXXYQXCYKQXQCSGYXXYQXYGYTQOHXHXPYXXXULCYEYCHZZCBWQBBWJQZSCSZSSLZYLKDESJZWMYMCYTSDSXXSCJPQQSQYLYYZYCMDJDZYWCBTJSYDJKCYDDJLBDJJSODZYSYXQQYXDHHGQQYQHDYXWGMMMAJDYBBBPPBCMUUPLJZSMTXERXJMHQNUTPJDCBSSMSSSTKJTSSMMTRCPLZSZMLQDSDMJMQPNQDXCFYNBFSDQXYXHYAYKQYDDLQYYYSSZBYDSLNTFQTZQPZMCHDHCZCWFDXTMYQSPHQYYXSRGJCWTJTZZQMGWJJTJHTQJBBHWZPXXHYQFXXQYWYYHYSCDYDHHQMNMTMWCPBSZPPZZGLMZFOLLCFWHMMSJZTTDHZZYFFYTZZGZYSKYJXQYJZQBHMBZZLYGHGFMSHPZFZSNCLPBQSNJXZSLXXFPMTYJYGBXLLDLXPZJYZJYHHZCYWHJYLSJEXFSZZYWXKZJLUYDTMLYMQJPWXYHXSKTQJEZRPXXZHHMHWQPWQLYJJQJJZSZCPHJLCHHNXJLQWZJHBMZYXBDHHYPZLHLHLGFWLCHYYTLHJXCJMSCPXSTKPNHQXSRTYXXTESYJCTLSSLSTDLLLWWYHDHRJZSFGXTSYCZYNYHTDHWJSLHTZDQDJZXXQHGYLTZPHCSQFCLNJTCLZPFSTPDYNYLGMJLLYCQHYSSHCHYLHQYQTMZYPBYWRFQYKQSYSLZDQJMPXYYSSRHZJNYWTQDFZBWWTWWRXCWHGYHXMKMYYYQMSMZHNGCEPMLQQMTCWCTMMPXJPJJHFXYYZSXZHTYBMSTSYJTTQQQYYLHYNPYQZLCYZHZWSMYLKFJXLWGXYPJYTYSYXYMZCKTTWLKSMZSYLMPWLZWXWQZSSAQSYXYRHSSNTSRAPXCPWCMGDXHXZDZYFJHGZTTSBJHGYZSZYSMYCLLLXBTYXHBBZJKSSDMALXHYCFYGMQYPJYCQXJLLLJGSLZGQLYCJCCZOTYXMTMTTLLWTGPXYMZMKLPSZZZXHKQYSXCTYJZYHXSHYXZKXLZWPSQPYHJWPJPWXQQYLXSDHMRSLZZYZWTTCYXYSZZSHBSCCSTPLWSSCJCHNLCGCHSSPHYLHFHHXJSXYLLNYLSZDHZXYLSXLWZYKCLDYAXZCMDDYSPJTQJZLNWQPSSSWCTSTSZLBLNXSMNYYMJQBQHRZWTYYDCHQLXKPZWBGQYBKFCMZWPZLLYYLSZYDWHXPSBCMLJBSCGBHXLQHYRLJXYSWXWXZSLDFHLSLYNJLZYFLYJYCDRJLFSYZFSLLCQYQFGJYHYXZLYLMSTDJCYHBZLLNWLXXYGYYHSMGDHXXHHLZZJZXCZZZCYQZFNGWPYLCPKPYYPMCLQKDGXZGGWQBDXZZKZFBXXLZXJTPJPTTBYTSZZDWSLCHZHSLTYXHQLHYXXXYYZYSWTXZKHLXZXZPYHGCHKCFSYHUTJRLXFJXPTZTWHPLYXFCRHXSHXKYXXYHZQDXQWULHYHMJTBFLKHTXCWHJFWJCFPQRYQXCYYYQYGRPYWSGSUNGWCHKZDXYFLXXHJJBYZWTSXXNCYJJYMSWZJQRMHXZWFQSYLZJZGBHYNSLBGTTCSYBYXXWXYHXYYXNSQYXMQYWRGYQLXBBZLJSYLPSYTJZYHYZAWLRORJMKSCZJXXXYXCHDYXRYXXJDTSQFXLYLTSFFYXLMTYJMJUYYYXLTZCSXQZQHZXLYYXZHDNBRXXXJCTYHLBRLMBRLLAXKYLLLJLYXXLYCRYLCJTGJCMTLZLLCYZZPZPCYAWHJJFYBDYYZSMPCKZDQYQPBPCJPDCYZMDPBCYYDYCNNPLMTMLRMFMMGWYZBSJGYGSMZQQQZTXMKQWGXLLPJGZBQCDJJJFPKJKCXBLJMSWMDTQJXLDLPPBXCWRCQFBFQJCZAHZGMYKPHYYHZYKNDKZMBPJYXPXYHLFPNYYGXJDBKXNXHJMZJXSTRSTLDXSKZYSYBZXJLXYSLBZYSLHXJPFXPQNBYLLJQKYGZMCYZZYMCCSLCLHZFWFWYXZMWSXTYNXJHPYYMCYSPMHYSMYDYSHQYZCHMJJMZCAAGCFJBBHPLYZYLXXSDJGXDHKXXTXXNBHRMLYJSLTXMRHNLXQJXYZLLYSWQGDLBJHDCGJYQYCMHWFMJYBMBYJYJWYMDPWHXQLDYGPDFXXBCGJSPCKRSSYZJMSLBZZJFLJJJLGXZGYXYXLSZQYXBEXYXHGCXBPLDYHWETTWWCJMBTXCHXYQXLLXFLYXLLJLSSFWDPZSMYJCLMWYTCZPCHQEKCQBWLCQYDPLQPPQZQFJQDJHYMMCXTXDRMJWRHXCJZYLQXDYYNHYYHRSLSRSYWWZJYMTLTLLGTQCJZYABTCKZCJYCCQLJZQXALMZYHYWLWDXZXQDLLQSHGPJFJLJHJABCQZDJGTKHSSTCYJLPSWZLXZXRWGLDLZRLZXTGSLLLLZLYXXWGDZYGBDPHZPBRLWSXQBPFDWOFMWHLYPCBJCCLDMBZPBZZLCYQXLDOMZBLZWPDWYYGDSTTHCSQSCCRSSSYSLFYBFNTYJSZDFNDPDHDZZMBBLSLCMYFFGTJJQWFTMTPJWFNLBZCMMJTGBDZLQLPYFHYYMJYLSDCHDZJWJCCTLJCLDTLJJCPDDSQDSSZYBNDBJLGGJZXSXNLYCYBJXQYCBYLZCFZPPGKCXZDZFZTJJFJSJXZBNZYJQTTYJYHTYCZHYMDJXTTMPXSPLZCDWSLSHXYPZGTFMLCJTYCBPMGDKWYCYZCDSZZYHFLYCTYGWHKJYYLSJCXGYWJCBLLCSNDDBTZBSCLYZCZZSSQDLLMQYYHFSLQLLXFTYHABXGWNYWYYPLLSDLDLLBJCYXJZMLHLJDXYYQYTDLLLBUGBFDFBBQJZZMDPJHGCLGMJJPGAEHHBWCQXAXHHHZCHXYPHJAXHLPHJPGPZJQCQZGJJZZUZDMQYYBZZPHYHYBWHAZYJHYKFGDPFQSDLZMLJXKXGALXZDAGLMDGXMWZQYXXDXXPFDMMSSYMPFMDMMKXKSYZYSHDZKXSYSMMZZZMSYDNZZCZXFPLSTMZDNMXCKJMZTYYMZMZZMSXHHDCZJEMXXKLJSTLWLSQLYJZLLZJSSDPPMHNLZJCZYHMXXHGZCJMDHXTKGRMXFWMCGMWKDTKSXQMMMFZZYDKMSCLCMPCGMHSPXQPZDSSLCXKYXTWLWJYAHZJGZQMCSNXYYMMPMLKJXMHLMLQMXCTKZMJQYSZJSYSZHSYJZJCDAJZYBSDQJZGWZQQXFKDMSDJLFWEHKZQKJPEYPZYSZCDWYJFFMZZYLTTDZZEFMZLBNPPLPLPEPSZALLTYLKCKQZKGENQLWAGYXYDPXLHSXQQWQCQXQCLHYXXMLYCCWLYMQYSKGCHLCJNSZKPYZKCQZQLJPDMDZHLASXLBYDWQLWDNBQCRYDDZTJYBKBWSZDXDTNPJDTCTQDFXQQMGNXECLTTBKPWSLCTYQLPWYZZKLPYGZCQQPLLKCCYLPQMZCZQCLJSLQZDJXLDDHPZQDLJJXZQDXYZQKZLJCYQDYJPPYPQYKJYRMPCBYMCXKLLZLLFQPYLLLMBSGLCYSSLRSYSQTMXYXZQZFDZUYSYZTFFMZZSMZQHZSSCCMLYXWTPZGXZJGZGSJSGKDDHTQGGZLLBJDZLCBCHYXYZHZFYWXYZYMSDBZZYJGTSMTFXQYXQSTDGSLNXDLRYZZLRYYLXQHTXSRTZNGZXBNQQZFMYKMZJBZYMKBPNLYZPBLMCNQYZZZSJZHJCTZKHYZZJRDYZHNPXGLFZTLKGJTCTSSYLLGZRZBBQZZKLPKLCZYSSUYXBJFPNJZZXCDWXZYJXZZDJJKGGRSRJKMSMZJLSJYWQSKYHQJSXPJZZZLSNSHRNYPZTWCHKLPSRZLZXYJQXQKYSJYCZTLQZYBBYBWZPQDWWYZCYTJCJXCKCWDKKZXSGKDZXWWYYJQYYTCYTDLLXWKCZKKLCCLZCQQDZLQLCSFQCHQHSFSMQZZLNBJJZBSJHTSZDYSJQJPDLZCDCWJKJZZLPYCGMZWDJJBSJQZSYZYHHXJPBJYDSSXDZNCGLQMBTSFSBPDZDLZNFGFJGFSMPXJQLMBLGQCYYXBQKDJJQYRFKZTJDHCZKLBSDZCFJTPLLJGXHYXZCSSZZXSTJYGKGCKGYOQXJPLZPBPGTGYJZGHZQZZLBJLSQFZGKQQJZGYCZBZQTLDXRJXBSXXPZXHYZYCLWDXJJHXMFDZPFZHQHQMQGKSLYHTYCGFRZGNQXCLPDLBZCSCZQLLJBLHBZCYPZZPPDYMZZSGYHCKCPZJGSLJLNSCDSLDLXBMSTLDDFJMKDJDHZLZXLSZQPQPGJLLYBDSZGQLBZLSLKYYHZTTNTJYQTZZPSZQZTLLJTYYLLQLLQYZQLBDZLSLYYZYMDFSZSNHLXZNCZQZPBWSKRFBSYZMTHBLGJPMCZZLSTLXSHTCSYZLZBLFEQHLXFLCJLYLJQCBZLZJHHSSTBRMHXZHJZCLXFNBGXGTQJCZTMSFZKJMSSNXLJKBHSJXNTNLZDNTLMSJXGZJYJCZXYJYJWRWWQNZTNFJSZPZSHZJFYRDJSFSZJZBJFZQZZHZLXFYSBZQLZSGYFTZDCSZXZJBQMSZKJRHYJZCKMJKHCHGTXKXQGLXPXFXTRTYLXJXHDTSJXHJZJXZWZLCQSBTXWXGXTXXHXFTSDKFJHZYJFJXRZSDLLLTQSQQZQWZXSYQTWGWBZCGZLLYZBCLMQQTZHZXZXLJFRMYZFLXYSQXXJKXRMQDZDMMYYBSQBHGZMWFWXGMXLZPYYTGZYCCDXYZXYWGSYJYZNBHPZJSQSYXSXRTFYZGRHZTXSZZTHCBFCLSYXZLZQMZLMPLMXZJXSFLBYZMYQHXJSXRXSQZZZSSLYFRCZJRCRXHHZXQYDYHXSJJHZCXZBTYNSYSXJBQLPXZQPYMLXZKYXLXCJLCYSXXZZLXDLLLJJYHZXGYJWKJRWYHCPSGNRZLFZWFZZNSXGXFLZSXZZZBFCSYJDBRJKRDHHGXJLJJTGXJXXSTJTJXLYXQFCSGSWMSBCTLQZZWLZZKXJMLTMJYHSDDBXGZHDLBMYJFRZFSGCLYJBPMLYSMSXLSZJQQHJZFXGFQFQBPXZGYYQXGZTCQWYLTLGWSGWHRLFSFGZJMGMGBGTJFSYZZGZYZAFLSSPMLPFLCWBJZCLJJMZLPJJLYMQDMYYYFBGYGYZMLYZDXQYXRQQQHSYYYQXYLJTYXFSFSLLGNQCYHYCWFHCCCFXPYLYPLLZYXXXXXKQHHXSHJZCFZSCZJXCPZWHHHHHAPYLQALPQAFYHXDYLUKMZQGGGDDESRNNZLTZGCHYPPYSQJJHCLLJTOLNJPZLJLHYMHEYDYDSQYCDDHGZUNDZCLZYZLLZNTNYZGSLHSLPJJBDGWXPCDUTJCKLKCLWKLLCASSTKZZDNQNTTLYYZSSYSSZZRYLJQKCQDHHCRXRZYDGRGCWCGZQFFFPPJFZYNAKRGYWYQPQXXFKJTSZZXSWZDDFBBXTBGTZKZNPZZPZXZPJSZBMQHKCYXYLDKLJNYPKYGHGDZJXXEAHPNZKZTZCMXCXMMJXNKSZQNMNLWBWWXJKYHCPSTMCSQTZJYXTPCTPDTNNPGLLLZSJLSPBLPLQHDTNJNLYYRSZFFJFQWDPHZDWMRZCCLODAXNSSNYZRESTYJWJYJDBCFXNMWTTBYLWSTSZGYBLJPXGLBOCLHPCBJLTMXZLJYLZXCLTPNCLCKXTPZJSWCYXSFYSZDKNTLBYJCYJLLSTGQCBXRYZXBXKLYLHZLQZLNZCXWJZLJZJNCJHXMNZZGJZZXTZJXYCYYCXXJYYXJJXSSSJSTSSTTPPGQTCSXWZDCSYFPTFBFHFBBLZJCLZZDBXGCXLQPXKFZFLSYLTUWBMQJHSZBMDDBCYSCCLDXYCDDQLYJJWMQLLCSGLJJSYFPYYCCYLTJANTJJPWYCMMGQYYSXDXQMZHSZXPFTWWZQSWQRFKJLZJQQYFBRXJHHFWJJZYQAZMYFRHCYYBYQWLPEXCCZSTYRLTTDMQLYKMBBGMYYJPRKZNPBSXYXBHYZDJDNGHPMFSGMWFZMFQMMBCMZZCJJLCNUXYQLMLRYGQZCYXZLWJGCJCGGMCJNFYZZJHYCPRRCMTZQZXHFQGTJXCCJEAQCRJYHPLQLSZDJRBCQHQDYRHYLYXJSYMHZYDWLDFRYHBPYDTSSCNWBXGLPZMLZZTQSSCPJMXXYCSJYTYCGHYCJWYRXXLFEMWJNMKLLSWTXHYYYNCMMCWJDQDJZGLLJWJRKHPZGGFLCCSCZMCBLTBHBQJXQDSPDJZZGKGLFQYWBZYZJLTSTDHQHCTCBCHFLQMPWDSHYYTQWCNZZJTLBYMBPDYYYXSQKXWYYFLXXNCWCXYPMAELYKKJMZZZBRXYYQJFLJPFHHHYTZZXSGQQMHSPGDZQWBWPJHZJDYSCQWZKTXXSQLZYYMYSDZGRXCKKUJLWPYSYSCSYZLRMLQSYLJXBCXTLWDQZPCYCYKPPPNSXFYZJJRCEMHSZMSXLXGLRWGCSTLRSXBZGBZGZTCPLUJLSLYLYMTXMTZPALZXPXJTJWTCYYZLBLXBZLQMYLXPGHDSLSSDMXMBDZZSXWHAMLCZCPJMCNHJYSNSYGCHSKQMZZQDLLKABLWJXSFMOCDXJRRLYQZKJMYBYQLYHETFJZFRFKSRYXFJTWDSXXSYSQJYSLYXWJHSNLXYYXHBHAWHHJZXWMYLJCSSLKYDZTXBZSYFDXGXZJKHSXXYBSSXDPYNZWRPTQZCZENYGCXQFJYKJBZMLJCMQQXUOXSLYXXLYLLJDZBTYMHPFSTTQQWLHOKYBLZZALZXQLHZWRRQHLSTMYPYXJJXMQSJFNBXYXYJXXYQYLTHYLQYFMLKLJTMLLHSZWKZHLJMLHLJKLJSTLQXYLMBHHLNLZXQJHXCFXXLHYHJJGBYZZKBXSCQDJQDSUJZYYHZHHMGSXCSYMXFEBCQWWRBPYYJQTYZCYQYQQZYHMWFFHGZFRJFCDPXNTQYZPDYKHJLFRZXPPXZDBBGZQSTLGDGYLCQMLCHHMFYWLZYXKJLYPQHSYWMQQGQZMLZJNSQXJQSYJYCBEHSXFSZPXZWFLLBCYYJDYTDTHWZSFJMQQYJLMQXXLLDTTKHHYBFPWTYYSQQWNQWLGWDEBZWCMYGCULKJXTMXMYJSXHYBRWFYMWFRXYQMXYSZTZZTFYKMLDHQDXWYYNLCRYJBLPSXCXYWLSPRRJWXHQYPHTYDNXHHMMYWYTZCSQMTSSCCDALWZTCPQPYJLLQZYJSWXMZZMMYLMXCLMXCZMXMZSQTZPPQQBLPGXQZHFLJJHYTJSRXWZXSCCDLXTYJDCQJXSLQYCLZXLZZXMXQRJMHRHZJBHMFLJLMLCLQNLDXZLLLPYPSYJYSXCQQDCMQJZZXHNPNXZMEKMXHYKYQLXSXTXJYYHWDCWDZHQYYBGYBCYSCFGPSJNZDYZZJZXRZRQJJYMCANYRJTLDPPYZBSTJKXXZYPFDWFGZZRPYMTNGXZQBYXNBUFNQKRJQZMJEGRZGYCLKXZDSKKNSXKCLJSPJYYZLQQJYBZSSQLLLKJXTBKTYLCCDDBLSPPFYLGYDTZJYQGGKQTTFZXBDKTYYHYBBFYTYYBCLPDYTGDHRYRNJSPTCSNYJQHKLLLZSLYDXXWBCJQSPXBPJZJCJDZFFXXBRMLAZHCSNDLBJDSZBLPRZTSWSBXBCLLXXLZDJZSJPYLYXXYFTFFFBHJJXGBYXJPMMMPSSJZJMTLYZJXSWXTYLEDQPJMYGQZJGDJLQJWJQLLSJGJGYGMSCLJJXDTYGJQJQJCJZCJGDZZSXQGSJGGCXHQXSNQLZZBXHSGZXCXYLJXYXYYDFQQJHJFXDHCTXJYRXYSQTJXYEFYYSSYYJXNCYZXFXMSYSZXYYSCHSHXZZZGZZZGFJDLTYLNPZGYJYZYYQZPBXQBDZTZCZYXXYHHSQXSHDHGQHJHGYWSZTMZMLHYXGEBTYLZKQWYTJZRCLEKYSTDBCYKQQSAYXCJXWWGSBHJYZYDHCSJKQCXSWXFLTYNYZPZCCZJQTZWJQDZZZQZLJJXLSBHPYXXPSXSHHEZTXFPTLQYZZXHYTXNCFZYYHXGNXMYWXTZSJPTHHGYMXMXQZXTSBCZYJYXXTYYZYPCQLMMSZMJZZLLZXGXZAAJZYXJMZXWDXZSXZDZXLEYJJZQBHZWZZZQTZPSXZTDSXJJJZNYAZPHXYYSRNQDTHZHYYKYJHDZXZLSWCLYBZYECWCYCRYLCXNHZYDZYDYJDFRJJHTRSQTXYXJRJHOJYNXELXSFSFJZGHPZSXZSZDZCQZBYYKLSGSJHCZSHDGQGXYZGXCHXZJWYQWGYHKSSEQZZNDZFKWYSSTCLZSTSYMCDHJXXYWEYXCZAYDMPXMDSXYBSQMJMZJMTZQLPJYQZCGQHXJHHLXXHLHDLDJQCLDWBSXFZZYYSCHTYTYYBHECXHYKGJPXHHYZJFXHWHBDZFYZBCAPNPGNYDMSXHMMMMAMYNBYJTMPXYYMCTHJBZYFCGTYHWPHFTWZZEZSBZEGPFMTSKFTYCMHFLLHGPZJXZJGZJYXZSBBQSCZZLZCCSTPGXMJSFTCCZJZDJXCYBZLFCJSYZFGSZLYBCWZZBYZDZYPSWYJZXZBDSYUXLZZBZFYGCZXBZHZFTPBGZGEJBSTGKDMFHYZZJHZLLZZGJQZLSFDJSSCBZGPDLFZFZSZYZYZSYGCXSNXXCHCZXTZZLJFZGQSQYXZJQDCCZTQCDXZJYQJQCHXZTDLGSCXZSYQJQTZWLQDQZTQCHQQJZYEZZZPBWKDJFCJPZTYPQYQTTYNLMBDKTJZPQZQZZFPZSBNJLGYJDXJDZZKZGQKXDLPZJTCJDQBXDJQJSTCKNXBXZMSLYJCQMTJQWWCJQNJNLLLHJCWQTBZQYDZCZPZZDZYDDCYZZZCCJTTJFZDPRRTZTJDCQTQZDTJNPLZBCLLCTZSXKJZQZPZLBZRBTJDCXFCZDBCCJJLTQQPLDCGZDBBZJCQDCJWYNLLZYZCCDWLLXWZLXRXNTQQCZXKQLSGDFQTDDGLRLAJJTKUYMKQLLTZYTDYYCZGJWYXDXFRSKSTQTENQMRKQZHHQKDLDAZFKYPBGGPZREBZZYKZZSPEGJXGYKQZZZSLYSYYYZWFQZYLZZLZHWCHKYPQGNPGBLPLRRJYXCCSYYHSFZFYBZYYTGZXYLXCZWXXZJZBLFFLGSKHYJZEYJHLPLLLLCZGXDRZELRHGKLZZYHZLYQSZZJZQLJZFLNBHGWLCZCFJYSPYXZLZLXGCCPZBLLCYBBBBUBBCBPCRNNZCZYRBFSRLDCGQYYQXYGMQZWTZYTYJXYFWTEHZZJYWLCCNTZYJJZDEDPZDZTSYQJHDYMBJNYJZLXTSSTPHNDJXXBYXQTZQDDTJTDYYTGWSCSZQFLSHLGLBCZPHDLYZJYCKWTYTYLBNYTSDSYCCTYSZYYEBHEXHQDTWNYGYCLXTSZYSTQMYGZAZCCSZZDSLZCLZRQXYYELJSBYMXSXZTEMBBLLYYLLYTDQYSHYMRQWKFKBFXNXSBYCHXBWJYHTQBPBSBWDZYLKGZSKYHXQZJXHXJXGNLJKZLYYCDXLFYFGHLJGJYBXQLYBXQPQGZTZPLNCYPXDJYQYDYMRBESJYYHKXXSTMXRCZZYWXYQYBMCLLYZHQYZWQXDBXBZWZMSLPDMYSKFMZKLZCYQYCZLQXFZZYDQZPZYGYJYZMZXDZFYFYTTQTZHGSPCZMLCCYTZXJCYTJMKSLPZHYSNZLLYTPZCTZZCKTXDHXXTQCYFKSMQCCYYAZHTJPCYLZLYJBJXTPNYLJYYNRXSYLMMNXJSMYBCSYSYLZYLXJJQYLDZLPQBFZZBLFNDXQKCZFYWHGQMRDSXYCYTXNQQJZYYPFZXDYZFPRXEJDGYQBXRCNFYYQPGHYJDYZXGRHTKYLNWDZNTSMPKLBTHBPYSZBZTJZSZZJTYYXZPHSSZZBZCZPTQFZMYFLYPYBBJQXZMXXDJMTSYSKKBJZXHJCKLPSMKYJZCXTMLJYXRZZQSLXXQPYZXMKYXXXJCLJPRMYYGADYSKQLSNDHYZKQXZYZTCGHZTLMLWZYBWSYCTBHJHJFCWZTXWYTKZLXQSHLYJZJXTMPLPYCGLTBZZTLZJCYJGDTCLKLPLLQPJMZPAPXYZLKKTKDZCZZBNZDYDYQZJYJGMCTXLTGXSZLMLHBGLKFWNWZHDXUHLFMKYSLGXDTWWFRJEJZTZHYDXYKSHWFZCQSHKTMQQHTZHYMJDJSKHXZJZBZZXYMPAGQMSTPXLSKLZYNWRTSQLSZBPSPSGZWYHTLKSSSWHZZLYYTNXJGMJSZSUFWNLSOZTXGXLSAMMLBWLDSZYLAKQCQCTMYCFJBSLXCLZZCLXXKSBZQCLHJPSQPLSXXCKSLNHPSFQQYTXYJZLQLDXZQJZDYYDJNZPTUZDSKJFSLJHYLZSQZLBTXYDGTQFDBYAZXDZHZJNHHQBYKNXJJQCZMLLJZKSPLDYCLBBLXKLELXJLBQYCXJXGCNLCQPLZLZYJTZLJGYZDZPLTQCSXFDMNYCXGBTJDCZNBGBQYQJWGKFHTNPYQZQGBKPBBYZMTJDYTBLSQMPSXTBNPDXKLEMYYCJYNZCTLDYKZZXDDXHQSHDGMZSJYCCTAYRZLPYLTLKXSLZCGGEXCLFXLKJRTLQJAQZNCMBYDKKCXGLCZJZXJHPTDJJMZQYKQSECQZDSHHADMLZFMMZBGNTJNNLGBYJBRBTMLBYJDZXLCJLPLDLPCQDHLXZLYCBLCXZZJADJLNZMMSSSMYBHBSQKBHRSXXJMXSDZNZPXLGBRHWGGFCXGMSKLLTSJYYCQLTSKYWYYHYWXBXQYWPYWYKQLSQPTNTKHQCWDQKTWPXXHCPTHTWUMSSYHBWCRWXHJMKMZNGWTMLKFGHKJYLSYYCXWHYECLQHKQHTTQKHFZLDXQWYZYYDESBPKYRZPJFYYZJCEQDZZDLATZBBFJLLCXDLMJSSXEGYGSJQXCWBXSSZPDYZCXDNYXPPZYDLYJCZPLTXLSXYZYRXCYYYDYLWWNZSAHJSYQYHGYWWAXTJZDAXYSRLTDPSSYYFNEJDXYZHLXLLLZQZSJNYQYQQXYJGHZGZCYJCHZLYCDSHWSHJZYJXCLLNXZJJYYXNFXMWFPYLCYLLABWDDHWDXJMCXZTZPMLQZHSFHZYNZTLLDYWLSLXHYMMYLMBWWKYXYADTXYLLDJPYBPWUXJMWMLLSAFDLLYFLBHHHBQQLTZJCQJLDJTFFKMMMBYTHYGDCQRDDWRQJXNBYSNWZDBYYTBJHPYBYTTJXAAHGQDQTMYSTQXKBTZPKJLZRBEQQSSMJJBDJOTGTBXPGBKTLHQXJJJCTHXQDWJLWRFWQGWSHCKRYSWGFTGYGBXSDWDWRFHWYTJJXXXJYZYSLPYYYPAYXHYDQKXSHXYXGSKQHYWFDDDPPLCJLQQEEWXKSYYKDYPLTJTHKJLTCYYHHJTTPLTZZCDLTHQKZXQYSTEEYWYYZYXXYYSTTJKLLPZMCYHQGXYHSRMBXPLLNQYDQHXSXXWGDQBSHYLLPJJJTHYJKYPPTHYYKTYEZYENMDSHLCRPQFDGFXZPSFTLJXXJBSWYYSKSFLXLPPLBBBLBSFXFYZBSJSSYLPBBFFFFSSCJDSTZSXZRYYSYFFSYZYZBJTBCTSBSDHRTJJBYTCXYJEYLXCBNEBJDSYXYKGSJZBXBYTFZWGENYHHTHZHHXFWGCSTBGXKLSXYWMTMBYXJSTZSCDYQRCYTWXZFHMYMCXLZNSDJTTTXRYCFYJSBSDYERXJLJXBBDEYNJGHXGCKGSCYMBLXJMSZNSKGXFBNBPTHFJAAFXYXFPXMYPQDTZCXZZPXRSYWZDLYBBKTYQPQJPZYPZJZNJPZJLZZFYSBTTSLMPTZRTDXQSJEHBZYLZDHLJSQMLHTXTJECXSLZZSPKTLZKQQYFSYGYWPCPQFHQHYTQXZKRSGTTSQCZLPTXCDYYZXSQZSLXLZMYCPCQBZYXHBSXLZDLTCDXTYLZJYYZPZYZLTXJSJXHLPMYTXCQRBLZSSFJZZTNJYTXMYJHLHPPLCYXQJQQKZZSCPZKSWALQSBLCCZJSXGWWWYGYKTJBBZTDKHXHKGTGPBKQYSLPXPJCKBMLLXDZSTBKLGGQKQLSBKKTFXRMDKBFTPZFRTBBRFERQGXYJPZSSTLBZTPSZQZSJDHLJQLZBPMSMMSXLQQNHKNBLRDDNXXDHDDJCYYGYLXGZLXSYGMQQGKHBPMXYXLYTQWLWGCPBMQXCYZYDRJBHTDJYHQSHTMJSBYPLWHLZFFNYPMHXXHPLTBQPFBJWQDBYGPNZTPFZJGSDDTQSHZEAWZZYLLTYYBWJKXXGHLFKXDJTMSZSQYNZGGSWQSPHTLSSKMCLZXYSZQZXNCJDQGZDLFNYKLJCJLLZLMZZNHYDSSHTHZZLZZBBHQZWWYCRZHLYQQJBEYFXXXWHSRXWQHWPSLMSSKZTTYGYQQWRSLALHMJTQJSMXQBJJZJXZYZKXBYQXBJXSHZTSFJLXMXZXFGHKZSZGGYLCLSARJYHSLLLMZXELGLXYDJYTLFBHBPNLYZFBBHPTGJKWETZHKJJXZXXGLLJLSTGSHJJYQLQZFKCGNNDJSSZFDBCTWWSEQFHQJBSAQTGYPQLBXBMMYWXGSLZHGLZGQYFLZBYFZJFRYSFMBYZHQGFWZSYFYJJPHZBYYZFFWODGRLMFTWLBZGYCQXCDJYGZYYYYTYTYDWEGAZYHXJLZYYHLRMGRXXZCLHNELJJTJTPWJYBJJBXJJTJTEEKHWSLJPLPSFYZPQQBDLQJJTYYQLYZKDKSQJYYQZLDQTGJQYZJSUCMRYQTHTEJMFCTYHYPKMHYZWJDQFHYYXWSHCTXRLJHQXHCCYYYJLTKTTYTMXGTCJTZAYYOCZLYLBSZYWJYTSJYHBYSHFJLYGJXXTMZYYLTXXYPZLXYJZYZYYPNHMYMDYYLBLHLSYYQQLLNJJYMSOYQBZGDLYXYLCQYXTSZEGXHZGLHWBLJHEYXTWQMAKBPQCGYSHHEGQCMWYYWLJYJHYYZLLJJYLHZYHMGSLJLJXCJJYCLYCJPCPZJZJMMYLCQLNQLJQJSXYJMLSZLJQLYCMMHCFMMFPQQMFYLQMCFFQMMMMHMZNFHHJGTTHHKHSLNCHHYQDXTMMQDCYZYXYQMYQYLTDCYYYZAZZCYMZYDLZFFFMMYCQZWZZMABTBYZTDMNZZGGDFTYPCGQYTTSSFFWFDTZQSSYSTWXJHXYTSXXYLBYQHWWKXHZXWZNNZZJZJJQJCCCHYYXBZXZCYZTLLCQXYNJYCYYCYNZZQYYYEWYCZDCJYCCHYJLBTZYYCQWMPWPYMLGKDLDLGKQQBGYCHJXY"; -//此处收录了375个多音字 -var oMultiDiff = { "19969": "DZ", "19975": "WM", "19988": "QJ", "20048": "YL", "20056": "SC", "20060": "NM", "20094": "QG", "20127": "QJ", "20167": "QC", "20193": "YG", "20250": "KH", "20256": "ZC", "20282": "SC", "20285": "QJG", "20291": "TD", "20314": "YD", "20340": "NE", "20375": "TD", "20389": "YJ", "20391": "CZ", "20415": "PB", "20446": "YS", "20447": "SQ", "20504": "TC", "20608": "KG", "20854": "QJ", "20857": "ZC", "20911": "PF", "20504": "TC", "20608": "KG", "20854": "QJ", "20857": "ZC", "20911": "PF", "20985": "AW", "21032": "PB", "21048": "XQ", "21049": "SC", "21089": "YS", "21119": "JC", "21242": "SB", "21273": "SC", "21305": "YP", "21306": "QO", "21330": "ZC", "21333": "SDC", "21345": "QK", "21378": "CA", "21397": "SC", "21414": "XS", "21442": "SC", "21477": "JG", "21480": "TD", "21484": "ZS", "21494": "YX", "21505": "YX", "21512": "HG", "21523": "XH", "21537": "PB", "21542": "PF", "21549": "KH", "21571": "E", "21574": "DA", "21588": "TD", "21589": "O", "21618": "ZC", "21621": "KHA", "21632": "ZJ", "21654": "KG", "21679": "LKG", "21683": "KH", "21710": "A", "21719": "YH", "21734": "WOE", "21769": "A", "21780": "WN", "21804": "XH", "21834": "A", "21899": "ZD", "21903": "RN", "21908": "WO", "21939": "ZC", "21956": "SA", "21964": "YA", "21970": "TD", "22003": "A", "22031": "JG", "22040": "XS", "22060": "ZC", "22066": "ZC", "22079": "MH", "22129": "XJ", "22179": "XA", "22237": "NJ", "22244": "TD", "22280": "JQ", "22300": "YH", "22313": "XW", "22331": "YQ", "22343": "YJ", "22351": "PH", "22395": "DC", "22412": "TD", "22484": "PB", "22500": "PB", "22534": "ZD", "22549": "DH", "22561": "PB", "22612": "TD", "22771": "KQ", "22831": "HB", "22841": "JG", "22855": "QJ", "22865": "XQ", "23013": "ML", "23081": "WM", "23487": "SX", "23558": "QJ", "23561": "YW", "23586": "YW", "23614": "YW", "23615": "SN", "23631": "PB", "23646": "ZS", "23663": "ZT", "23673": "YG", "23762": "TD", "23769": "ZS", "23780": "QJ", "23884": "QK", "24055": "XH", "24113": "DC", "24162": "ZC", "24191": "GA", "24273": "QJ", "24324": "NL", "24377": "TD", "24378": "QJ", "24439": "PF", "24554": "ZS", "24683": "TD", "24694": "WE", "24733": "LK", "24925": "TN", "25094": "ZG", "25100": "XQ", "25103": "XH", "25153": "PB", "25170": "PB", "25179": "KG", "25203": "PB", "25240": "ZS", "25282": "FB", "25303": "NA", "25324": "KG", "25341": "ZY", "25373": "WZ", "25375": "XJ", "25384": "A", "25457": "A", "25528": "SD", "25530": "SC", "25552": "TD", "25774": "ZC", "25874": "ZC", "26044": "YW", "26080": "WM", "26292": "PB", "26333": "PB", "26355": "ZY", "26366": "CZ", "26397": "ZC", "26399": "QJ", "26415": "ZS", "26451": "SB", "26526": "ZC", "26552": "JG", "26561": "TD", "26588": "JG", "26597": "CZ", "26629": "ZS", "26638": "YL", "26646": "XQ", "26653": "KG", "26657": "XJ", "26727": "HG", "26894": "ZC", "26937": "ZS", "26946": "ZC", "26999": "KJ", "27099": "KJ", "27449": "YQ", "27481": "XS", "27542": "ZS", "27663": "ZS", "27748": "TS", "27784": "SC", "27788": "ZD", "27795": "TD", "27812": "O", "27850": "PB", "27852": "MB", "27895": "SL", "27898": "PL", "27973": "QJ", "27981": "KH", "27986": "HX", "27994": "XJ", "28044": "YC", "28065": "WG", "28177": "SM", "28267": "QJ", "28291": "KH", "28337": "ZQ", "28463": "TL", "28548": "DC", "28601": "TD", "28689": "PB", "28805": "JG", "28820": "QG", "28846": "PB", "28952": "TD", "28975": "ZC", "29100": "A", "29325": "QJ", "29575": "SL", "29602": "FB", "30010": "TD", "30044": "CX", "30058": "PF", "30091": "YSP", "30111": "YN", "30229": "XJ", "30427": "SC", "30465": "SX", "30631": "YQ", "30655": "QJ", "30684": "QJG", "30707": "SD", "30729": "XH", "30796": "LG", "30917": "PB", "31074": "NM", "31085": "JZ", "31109": "SC", "31181": "ZC", "31192": "MLB", "31293": "JQ", "31400": "YX", "31584": "YJ", "31896": "ZN", "31909": "ZY", "31995": "XJ", "32321": "PF", "32327": "ZY", "32418": "HG", "32420": "XQ", "32421": "HG", "32438": "LG", "32473": "GJ", "32488": "TD", "32521": "QJ", "32527": "PB", "32562": "ZSQ", "32564": "JZ", "32735": "ZD", "32793": "PB", "33071": "PF", "33098": "XL", "33100": "YA", "33152": "PB", "33261": "CX", "33324": "BP", "33333": "TD", "33406": "YA", "33426": "WM", "33432": "PB", "33445": "JG", "33486": "ZN", "33493": "TS", "33507": "QJ", "33540": "QJ", "33544": "ZC", "33564": "XQ", "33617": "YT", "33632": "QJ", "33636": "XH", "33637": "YX", "33694": "WG", "33705": "PF", "33728": "YW", "33882": "SR", "34067": "WM", "34074": "YW", "34121": "QJ", "34255": "ZC", "34259": "XL", "34425": "JH", "34430": "XH", "34485": "KH", "34503": "YS", "34532": "HG", "34552": "XS", "34558": "YE", "34593": "ZL", "34660": "YQ", "34892": "XH", "34928": "SC", "34999": "QJ", "35048": "PB", "35059": "SC", "35098": "ZC", "35203": "TQ", "35265": "JX", "35299": "JX", "35782": "SZ", "35828": "YS", "35830": "E", "35843": "TD", "35895": "YG", "35977": "MH", "36158": "JG", "36228": "QJ", "36426": "XQ", "36466": "DC", "36710": "JC", "36711": "ZYG", "36767": "PB", "36866": "SK", "36951": "YW", "37034": "YX", "37063": "XH", "37218": "ZC", "37325": "ZC", "38063": "PB", "38079": "TD", "38085": "QY", "38107": "DC", "38116": "TD", "38123": "YD", "38224": "HG", "38241": "XTC", "38271": "ZC", "38415": "YE", "38426": "KH", "38461": "YD", "38463": "AE", "38466": "PB", "38477": "XJ", "38518": "YT", "38551": "WK", "38585": "ZC", "38704": "XS", "38739": "LJ", "38761": "GJ", "38808": "SQ", "39048": "JG", "39049": "XJ", "39052": "HG", "39076": "CZ", "39271": "XT", "39534": "TD", "39552": "TD", "39584": "PB", "39647": "SB", "39730": "LG", "39748": "TPB", "40109": "ZQ", "40479": "ND", "40516": "HG", "40536": "HG", "40583": "QJ", "40765": "YQ", "40784": "QJ", "40840": "YK", "40863": "QJG" }; - - -function checkCh(ch) { - var uni = ch.charCodeAt(0); - //如果不在汉字处理范围之内,返回原字符,也可以调用自己的处理函数 - if (uni > 40869 || uni < 19968) - return ch; //dealWithOthers(ch); - //检查是否是多音字,是按多音字处理,不是就直接在strChineseFirstPY字符串中找对应的首字母 - return (oMultiDiff[uni] ? oMultiDiff[uni] : (strChineseFirstPY.charAt(uni - 19968))); -} - -function mkRslt(arr) { - var arrRslt = [""]; - for (var i = 0, len = arr.length; i < len; i++) { - var str = arr[i]; - var strlen = str.length; - if (strlen == 1) { - for (var k = 0; k < arrRslt.length; k++) { - arrRslt[k] += str; - } - } else { - var tmpArr = arrRslt.slice(0); - arrRslt = []; - for (k = 0; k < strlen; k++) { - //复制一个相同的arrRslt - var tmp = tmpArr.slice(0); - //把当前字符str[k]添加到每个元素末尾 - for (var j = 0; j < tmp.length; j++) { - tmp[j] += str.charAt(k); - } - //把复制并修改后的数组连接到arrRslt上 - arrRslt = arrRslt.concat(tmp); - } - } - } - return arrRslt; -} -//两端去空格函数 -String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*$)/g, ""); } - -//参数——中文字符串 -//返回值——拼音首字母串数组 -export function getFirstLetterList(str) { - if (typeof(str) != "string") - throw new Error(-1, "请传入字符串类型的参数!"); - var arrResult = new Array(); //保存中间结果的数组 - for (var i = 0, len = str.length; i < len; i++) { - //获得unicode码 - var ch = str.charAt(i); - //检查该unicode码是否在处理范围之内,在则返回该码对映汉字的拼音首字母,不在则调用其它函数处理 - arrResult.push(checkCh(ch)); - } - //处理arrResult,返回所有可能的拼音首字母串数组 - return mkRslt(arrResult); -} - -// 判断字符串是否全是中文 -function isAllChinese(str) { - return /^[\u4E00-\u9FA5]+$/.test(str); -} - -// 判断字符是否为中文 -function isChinese(char) { - return /^[\u4E00-\u9FA5]$/.test(char); -} - -// 中文拼音名称排序 -export const sortListByCN = (vodList,key,order) => { - if(!key){ - return vodList - } - order = order||'asc'; // 默认正序 - let ASCarr = vodList.sort((a, b) => { - a = a[key]; - b = b[key]; - // 数字排在字符串前面 - if (typeof a === 'number' && typeof b === 'string') { - return -1; - } - - if (typeof a === 'string' && typeof b === 'number') { - return 1; - } - - // 当存在非数字时 - if (isNaN(a) || isNaN(b)) { - - // 全汉字的排在非全汉字的后面 - if (isAllChinese(a) && !isAllChinese(b)) { - return 1; - } - - if (!isAllChinese(a) && isAllChinese(b)) { - return -1; - } - - // 存在非数字的数据时,都转为字符串进行比较 - a = a.toString(); - b = b.toString(); - - let result = 0; - - // 依次比较两个字符串的各项字符 - for (let index = 0; index < ((a.length - b.length) ? b.length : a.length); index++) { - - // 汉字排在非汉字的后面 - if (!isChinese(a[index]) && isChinese(b[index])) { - result = -1; - } - - if (isChinese(a[index]) && !isChinese(b[index])) { - result = 1; - } - - // 若两个汉字进行比较,则比较他们的拼音首字母 - if (isChinese(a[index]) && isChinese(b[index])) { - let pinyinA = getFirstLetterList(a[index]).toString(); - let pinyinB = getFirstLetterList(b[index]).toString(); - - result = pinyinA.localeCompare(pinyinB, 'zh-Hans-CN', { sensitivity: 'accent' }); - } - - // 若已经比较出结果,则跳出循环,不再继续比较剩余字符 - if (result !== 0) { - break - } - } - - // 只要有一个无法转换为数字——转换为字符串进行比较——先按字符排序,然后按照数字排序 - return result || a.toString().localeCompare(b.toString(), 'zh-Hans-CN', { sensitivity: 'accent' }); - } else { - // 都能转换为数字——转换为数字进行比较——从小到大排序 - return Number(a) - Number(b); - } - }); - if(order==='desc'){ - ASCarr.reverse(); - } - return ASCarr -}; - -// 首字母开头排序 -export const sortListByFirst = (vodList,key) => { - key = key||'vod_name'; - // 名字以特殊符号开头的应用列表 - const symbol_list = []; - // 名字以中文开头的应用列表 - const cn_list = []; - // 名字以英文开头的应用列表 - const en_list = []; - // 名字以数字开头的应用列表 - const num_list = []; - - vodList.forEach((vod) => { - const { vod_name } = vod; - //通过正则进行数据分类 - if (/[\u4e00-\u9fa5]/.test(vod_name[0])) { - cn_list.push(vod); - } else if (/[a-zA-Z]/.test(vod_name[0])) { - en_list.push(vod); - } else if (/[\d]/.test(vod_name[0])) { - num_list.push(vod); - } else { - symbol_list.push(vod); - } - }); - //按照要求的方式进行数据排序重组 - const newList = [ - ...cn_list.sort((a, b) => a.vod_name[0]?.localeCompare(b.vod_name[0])), - ...en_list.sort((a, b) => a.vod_name[0].localeCompare(b.vod_name[0])),//localeCompare可以不区分大小写的进行排序 - ...num_list.sort((a, b) => a.vod_name[0] - b.vod_name[0]), - ...symbol_list.sort((a, b) => a.vod_name[0] - b.vod_name[0]) - ]; - return newList -}; \ No newline at end of file diff --git a/lib/token.txt b/lib/token.txt deleted file mode 100644 index 8142f786..00000000 --- a/lib/token.txt +++ /dev/null @@ -1 +0,0 @@ -52eb497172f44b498943ac642d62113e \ No newline at end of file diff --git a/lib/模板.js b/lib/模板.js deleted file mode 100644 index 38018333..00000000 --- a/lib/模板.js +++ /dev/null @@ -1,301 +0,0 @@ -if (typeof Object.assign != 'function') { - Object.assign = function () { - var target = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - return target; -}; -} -function getMubans() { - var mubanDict = { // 模板字典 - mxpro: { - title: '', - host: '', - // homeUrl:'/', - url: '/vodshow/fyclass--------fypage---.html', - searchUrl: '/vodsearch/**----------fypage---.html', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: {//网站的请求头,完整支持所有的,常带ua和cookies - 'User-Agent': 'MOBILE_UA', - // "Cookie": "searchneed=ok" - }, - class_parse: '.navbar-items li:gt(2):lt(8);a&&Text;a&&href;/(\\d+).html', - play_parse: true, - lazy: '', - limit: 6, - 推荐: '.tab-list.active;a.module-poster-item.module-item;.module-poster-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: 'body a.module-poster-item.module-item;a&&title;.lazyload&&data-original;.module-item-note&&Text;a&&href', - 二级: { - "title": "h1&&Text;.module-info-tag&&Text", - "img": ".lazyload&&data-original", - "desc": ".module-info-item:eq(1)&&Text;.module-info-item:eq(2)&&Text;.module-info-item:eq(3)&&Text", - "content": ".module-info-introduction&&Text", - "tabs": ".module-tab-item", - "lists": ".module-play-list:eq(#id) a" - }, - 搜索: 'body .module-item;.module-card-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href;.module-info-item-content&&Text', - }, - mxone5: { - title: '', - host: '', - url: '/show/fyclass--------fypage---.html', - searchUrl: '/search/**----------fypage---.html', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - class_parse: '.nav-menu-items&&li;a&&Text;a&&href;.*/(.*?).html', - play_parse: true, - lazy: '', - limit: 6, - 推荐: '.module-list;.module-items&&.module-item;a&&title;img&&data-src;.module-item-text&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: '.module-items .module-item;a&&title;img&&data-src;.module-item-text&&Text;a&&href', - 二级: { - "title": "h1&&Text;.tag-link&&Text", - "img": ".module-item-pic&&img&&data-src", - "desc": ".video-info-items:eq(0)&&Text;.video-info-items:eq(1)&&Text;.video-info-items:eq(2)&&Text;.video-info-items:eq(3)&&Text", - "content": ".vod_content&&Text", - "tabs": ".module-tab-item", - "lists": ".module-player-list:eq(#id)&&.scroll-content&&a" - }, - 搜索: '.module-items .module-search-item;a&&title;img&&data-src;.video-serial&&Text;a&&href', - }, - 首图: { - title: '', - host: '', - url: '/vodshow/fyclass--------fypage---/', - searchUrl: '/vodsearch/**----------fypage---.html', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: {//网站的请求头,完整支持所有的,常带ua和cookies - 'User-Agent': 'MOBILE_UA', - // "Cookie": "searchneed=ok" - }, - class_parse: '.myui-header__menu li.hidden-sm:gt(0):lt(5);a&&Text;a&&href;/(\\d+).html', - play_parse: true, - lazy: '', - limit: 6, - 推荐: 'ul.myui-vodlist.clearfix;li;a&&title;a&&data-original;.pic-text&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: '.myui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href', - 二级: { - "title": ".myui-content__detail .title&&Text;.myui-content__detail p:eq(-2)&&Text", - "img": ".myui-content__thumb .lazyload&&data-original", - "desc": ".myui-content__detail p:eq(0)&&Text;.myui-content__detail p:eq(1)&&Text;.myui-content__detail p:eq(2)&&Text", - "content": ".content&&Text", - "tabs": ".nav-tabs:eq(0) li", - "lists": ".myui-content__list:eq(#id) li" - }, - 搜索: '#searchList li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text', - }, - 首图2: { - title: '', - host: '', - url: '/list/fyclass-fypage.html', - searchUrl: '/vodsearch/**----------fypage---.html', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: { - 'User-Agent': 'UC_UA', - // "Cookie": "" - }, - // class_parse:'.stui-header__menu li:gt(0):lt(7);a&&Text;a&&href;/(\\d+).html', - class_parse: '.stui-header__menu li:gt(0):lt(7);a&&Text;a&&href;.*/(.*?).html', - play_parse: true, - lazy: '', - limit: 6, - 推荐: 'ul.stui-vodlist.clearfix;li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: '.stui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href', - 二级: { - "title": ".stui-content__detail .title&&Text;.stui-content__detail p:eq(-2)&&Text", - "img": ".stui-content__thumb .lazyload&&data-original", - "desc": ".stui-content__detail p:eq(0)&&Text;.stui-content__detail p:eq(1)&&Text;.stui-content__detail p:eq(2)&&Text", - "content": ".detail&&Text", - "tabs": ".stui-vodlist__head h3", - "lists": ".stui-content__playlist:eq(#id) li" - }, - 搜索: 'ul.stui-vodlist__media:eq(0) li,ul.stui-vodlist:eq(0) li,#searchList li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text', - 搜索1: 'ul.stui-vodlist&&li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text', - 搜索2: 'ul.stui-vodlist__media&&li;a&&title;.lazyload&&data-original;.text-muted&&Text;a&&href;.text-muted:eq(-1)&&Text', - }, - 默认: { - title: '', - host: '', - url: '/vodshow/fyclass--------fypage---.html', - searchUrl: '/vodsearch/-------------.html?wd=**', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: { - 'User-Agent': 'MOBILE_UA', - }, - play_parse: true, - lazy: '', - limit: 6, - double: true, // 推荐内容是否双层定位 - }, - vfed: { - title: '', - host: '', - url: '/index.php/vod/show/id/fyclass/page/fypage.html', - searchUrl: '/index.php/vod/search/page/fypage/wd/**.html', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: { - 'User-Agent': 'UC_UA', - }, - // class_parse:'.fed-pops-navbar&&ul.fed-part-rows&&a.fed-part-eone:gt(0):lt(5);a&&Text;a&&href;.*/(.*?).html', - class_parse: '.fed-pops-navbar&&ul.fed-part-rows&&a;a&&Text;a&&href;.*/(.*?).html', - play_parse: true, - lazy: '', - limit: 6, - 推荐: 'ul.fed-list-info.fed-part-rows;li;a.fed-list-title&&Text;a&&data-original;.fed-list-remarks&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: '.fed-list-info&&li;a.fed-list-title&&Text;a&&data-original;.fed-list-remarks&&Text;a&&href', - 二级: { - "title": "h1.fed-part-eone&&Text;.fed-deta-content&&.fed-part-rows&&li&&Text", - "img": ".fed-list-info&&a&&data-original", - "desc": ".fed-deta-content&&.fed-part-rows&&li:eq(1)&&Text;.fed-deta-content&&.fed-part-rows&&li:eq(2)&&Text;.fed-deta-content&&.fed-part-rows&&li:eq(3)&&Text", - "content": ".fed-part-esan&&Text", - "tabs": ".fed-drop-boxs&&.fed-part-rows&&li", - "lists": ".fed-play-item:eq(#id)&&ul:eq(1)&&li" - }, - 搜索: '.fed-deta-info;h1&&Text;.lazyload&&data-original;.fed-list-remarks&&Text;a&&href;.fed-deta-content&&Text', - }, - 海螺3: { - title: '', - host: '', - searchUrl: '/v_search/**----------fypage---.html', - url: '/vod_____show/fyclass--------fypage---.html', - headers: { - 'User-Agent': 'MOBILE_UA' - }, - timeout: 5000, - class_parse: 'body&&.hl-nav li:gt(0);a&&Text;a&&href;.*/(.*?).html', - cate_exclude: '明星|专题|最新|排行', - limit: 40, - play_parse: true, - lazy: '', - 推荐: '.hl-vod-list;li;a&&title;a&&data-original;.remarks&&Text;a&&href', - double: true, - 一级: '.hl-vod-list&&.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href', - 二级: { - "title": ".hl-infos-title&&Text;.hl-text-conch&&Text", - "img": ".hl-lazy&&data-original", - "desc": ".hl-infos-content&&.hl-text-conch&&Text", - "content": ".hl-content-text&&Text", - "tabs": ".hl-tabs&&a", - "lists": ".hl-plays-list:eq(#id)&&li" - }, - 搜索: '.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - }, - 海螺2: { - title: '', - host: '', - searchUrl: '/index.php/vod/search/page/fypage/wd/**/', - url: '/index.php/vod/show/id/fyclass/page/fypage/', - headers: { - 'User-Agent': 'MOBILE_UA' - }, - timeout: 5000, - class_parse: '#nav-bar li;a&&Text;a&&href;id/(.*?)/', - limit: 40, - play_parse: true, - lazy: '', - 推荐: '.list-a.size;li;a&&title;.lazy&&data-original;.bt&&Text;a&&href', - double: true, - 一级: '.list-a&&li;a&&title;.lazy&&data-original;.list-remarks&&Text;a&&href', - 二级: { - "title": "h2&&Text;.deployment&&Text", - "img": ".lazy&&data-original", - "desc": ".deployment&&Text", - "content": ".ec-show&&Text", - "tabs": "#tag&&a", - "lists": ".play_list_box:eq(#id)&&li" - }, - 搜索: '.search-list;a&&title;.lazy&&data-original;.deployment&&Text;a&&href', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - }, - 短视: { - title: '', - host: '', - // homeUrl:'/', - url: '/channel/fyclass-fypage.html', - searchUrl: '/search.html?wd=**', - searchable: 2,//是否启用全局搜索, - quickSearch: 0,//是否启用快速搜索, - filterable: 0,//是否启用分类筛选, - headers: {//网站的请求头,完整支持所有的,常带ua和cookies - 'User-Agent': 'MOBILE_UA', - // "Cookie": "searchneed=ok" - }, - class_parse: '.menu_bottom ul li;a&&Text;a&&href;.*/(.*?).html', - cate_exclude: '解析|动态', - play_parse: true, - lazy: '', - limit: 6, - 推荐: '.indexShowBox;ul&&li;a&&title;img&&data-src;.s1&&Text;a&&href', - double: true, // 推荐内容是否双层定位 - 一级: '.pic-list&&li;a&&title;img&&data-src;.s1&&Text;a&&href', - 二级: { - "title": "h1&&Text;.content-rt&&p:eq(0)&&Text", - "img": ".img&&img&&data-src", - "desc": ".content-rt&&p:eq(1)&&Text;.content-rt&&p:eq(2)&&Text;.content-rt&&p:eq(3)&&Text;.content-rt&&p:eq(4)&&Text;.content-rt&&p:eq(5)&&Text", - "content": ".zkjj_a&&Text", - "tabs": ".py-tabs&&option", - "lists": ".player:eq(#id) li" - }, - 搜索: '.sr_lists&&ul&&li;h3&&Text;img&&data-src;.int&&p:eq(0)&&Text;a&&href', - }, - 短视2:{ - title: '', - host: '', - class_name:'电影&电视剧&综艺&动漫', - class_url:'1&2&3&4', - searchUrl: '/index.php/ajax/suggest?mid=1&wd=**', - searchable: 2, - quickSearch: 0, - headers:{'User-Agent':'MOBILE_UA'}, - url: '/index.php/api/vod#type=fyclass&page=fypage', - filterable:0,//是否启用分类筛选, - filter_url:'', - filter: {}, - filter_def:{}, - detailUrl:'/index.php/vod/detail/id/fyid.html', - 推荐:'.list-vod.flex .public-list-box;a&&title;.lazy&&data-original;.public-list-prb&&Text;a&&href', - 一级:'js:let body=input.split("#")[1];let t=Math.round(new Date/1e3).toString();let key=md5("DS"+t+"DCC147D11943AF75");let url=input.split("#")[0];body=body+"&time="+t+"&key="+key;print(body);fetch_params.body=body;let html=post(url,fetch_params);let data=JSON.parse(html);VODS=data.list.map(function(it){it.vod_pic=urljoin2(input.split("/i")[0],it.vod_pic);return it});', - 二级:{ - "title":".slide-info-title&&Text;.slide-info:eq(3)--strong&&Text", - "img":".detail-pic&&data-original", - "desc":".fraction&&Text;.slide-info-remarks:eq(1)&&Text;.slide-info-remarks:eq(2)&&Text;.slide-info:eq(2)--strong&&Text;.slide-info:eq(1)--strong&&Text", - "content":"#height_limit&&Text", - "tabs":".anthology.wow.fadeInUp.animated&&.swiper-wrapper&&a", - "tab_text":".swiper-slide&&Text", - "lists":".anthology-list-box:eq(#id) li" - }, - 搜索:'json:list;name;pic;;id', - } - }; - return JSON.parse(JSON.stringify(mubanDict)); -} -var mubanDict = getMubans(); -var muban = getMubans(); -export default {muban,getMubans}; \ No newline at end of file