This commit is contained in:
Liu committed 2026-06-11 02:27:52 +08:00
1 parent 2d385a1497
commit 4f89a5c886
89 files changed
+5312 -36791

No files matched your search

-202
View File
@@ -1,202 +0,0 @@
import { load, _ } from 'assets://js/lib/cat.js';
let HOST = 'https://www.budaichuchen.net';
const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
const DefaultHeader = {
'User-Agent': UA,
'Referer': HOST + '/',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
};
async function request(url, options = {}) {
try {
const optObj = {
headers: options.headers || DefaultHeader,
timeout: 10000,
method: options.method || 'GET',
data: options.data || ''
};
const res = await req(url, optObj);
return res?.content ?? '';
} catch (e) {
return '';
}
}
function parseHtml(html) {
return load(html);
}
async function init(cfg) {
if (cfg.ext && typeof cfg.ext === 'string') {
HOST = cfg.ext;
}
}
async function home(filter) {
const classes = [
{ type_id: '1', type_name: '电影' },
{ type_id: '2', type_name: '电视剧' },
{ type_id: '3', type_name: '综艺' },
{ type_id: '4', type_name: '动漫' },
{ type_id: '5', type_name: '短剧' }
];
return JSON.stringify({ class: classes });
}
async function homeVod() {
const html = await request(HOST);
if (!html) return JSON.stringify({ list: [] });
const $ = parseHtml(html);
let videos = [];
$('.public-list-box').each((_, el) => {
const a = $(el).find('.public-list-exp');
const href = a.attr('href') || '';
if (href.includes('/detail/')) {
videos.push({
vod_id: href.match(/detail\/(.*?)\.html/)[1],
vod_name: a.attr('title'),
vod_pic: a.find('img').attr('data-src') || a.find('img').attr('src'),
vod_remarks: $(el).find('.public-list-prb').text().trim()
});
}
});
return JSON.stringify({ list: videos });
}
async function category(tid, pg, filter, extend) {
const area = extend.area || '';
const by = extend.by || 'time';
const clazz = extend.class || '';
const year = extend.year || '';
const lang = extend.lang || '';
const letter = extend.letter || '';
const url = `${HOST}/cupfox-list/${tid}-${area}-${by}-${clazz}-${lang}-${letter}---${pg}---${year}.html`;
const html = await request(url);
if (!html) return JSON.stringify({ list: [] });
const $ = parseHtml(html);
let videos = [];
$('.public-list-box').each((_, el) => {
const a = $(el).find('.public-list-exp');
const href = a.attr('href') || '';
if (href.includes('/detail/')) {
videos.push({
vod_id: href.match(/detail\/(.*?)\.html/)[1],
vod_name: a.attr('title'),
vod_pic: $(el).find('img').attr('data-src') || $(el).find('img').attr('src'),
vod_remarks: $(el).find('.public-list-prb').text().trim()
});
}
});
return JSON.stringify({ page: parseInt(pg), list: videos });
}
async function detail(id) {
const url = `${HOST}/detail/${id}.html`;
const html = await request(url);
if (!html) return "{}";
const $ = parseHtml(html);
const vod = {
vod_id: id,
vod_name: $('.slide-info-title').text().trim(),
vod_pic: $('.detail-pic img').attr('data-src') || $('.detail-pic img').attr('src'),
vod_content: $('#height_limit').text().trim(),
vod_play_from: [],
vod_play_url: []
};
$('.anthology-tab a').each((_, el) => {
const name = $(el).text().trim().replace(/\s/g, '').replace(/\(\d+\)/, '');
if (name) vod.vod_play_from.push(name);
});
$('.anthology-list-box').each((_, el) => {
let items = [];
$(el).find('ul li a').each((_, a) => {
const name = $(a).text().trim();
const href = $(a).attr('href');
if (href) {
const playMatch = href.match(/play\/(.*?)\.html/);
if (playMatch) items.push(`${name}$${playMatch[1]}`);
}
});
items.reverse();
vod.vod_play_url.push(items.join('#'));
});
vod.vod_play_from = vod.vod_play_from.join('$$$');
vod.vod_play_url = vod.vod_play_url.join('$$$');
return JSON.stringify({ list: [vod] });
}
async function search(wd, quick) {
const url = `${HOST}/cupfox-search/${encodeURIComponent(wd)}----------1---.html`;
const html = await request(url);
if (!html) return JSON.stringify({ list: [] });
const $ = parseHtml(html);
let videos = [];
$('.search-box').each((_, el) => {
const a = $(el).find('.public-list-exp');
const href = a.attr('href') || '';
if (href.includes('/detail/')) {
videos.push({
vod_id: href.match(/detail\/(.*?)\.html/)[1],
vod_name: $(el).find('.thumb-txt a').text().trim(),
vod_pic: a.find('img').attr('data-src') || a.find('img').attr('src'),
vod_remarks: a.find('.public-list-prb').text().trim()
});
}
});
return JSON.stringify({ list: videos });
}
async function play(flag, id, flags) {
try {
const url = `${HOST}/play/${id}.html`;
const html = await request(url);
if (!html) return JSON.stringify({ parse: 0, url: '' });
const match = html.match(/var\s+player_aaaa\s*=\s*(\{.*?\});/);
if (!match) return JSON.stringify({ parse: 1, url: url });
const config = JSON.parse(match[1]);
const rawUrl = config.url || '';
const from = config.from || '';
if (rawUrl.startsWith('http')) {
const isDirect = rawUrl.includes('.m3u8') || rawUrl.includes('.mp4');
return JSON.stringify({
parse: isDirect ? 0 : 1,
url: rawUrl,
header: DefaultHeader
});
}
if (from === 'JD4K' || from === 'JD' || rawUrl.startsWith('JD-')) {
const jxUrl = 'https://fgsrg.hzqingshan.com/player/?url=' + rawUrl;
return JSON.stringify({
parse: 1,
url: jxUrl,
header: DefaultHeader
});
}
return JSON.stringify({
parse: 1,
url: rawUrl || url,
header: DefaultHeader
});
} catch (e) {
return JSON.stringify({ parse: 1, url: url });
}
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search
};
}
-3
View File
@@ -1,3 +0,0 @@
// 本资源来源于互联网公开渠道,仅可用于个人学习爬虫技术。
// 严禁将其用于任何商业用途,下载后请于 24 小时内删除,搜索结果均来自源站,本人不承担任何责任。
import{Crypto as t,_ as e}from"assets://js/lib/cat.js";let n="https://api.dbokutv.com";const o={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)",Connection:"Keep-Alive",Referer:"https://www.duboku.tv/"};async function r(t){}async function a(t){const e=[{type_id:2,type_name:"连续剧"},{type_id:3,type_name:"综艺"},{type_id:1,type_name:"电影"},{type_id:4,type_name:"动漫"}],r={},a=e.map(async t=>{const e=t.type_id,a=f(`${n}/vodshow/${e}-----------`);try{const t=await req(a,{headers:o}),n=JSON.parse(t.content);if(n&&n.FilterList){const t=[];for(const e of n.FilterList){let n="";switch(e.Class){case"剧情":n="class";break;case"地区":n="area";break;case"年份":n="year";break;case"语言":n="lang";break;case"字母":n="letter";break;case"排序":n="sort";break;case"类型":n="scat"}if(n&&e.OptionList&&e.OptionList.length>0){const o=[];let r="";"sort"===n?(e.OptionList.forEach(t=>{o.push({n:t.Option,v:t.Option})}),r="时间"):(o.push({n:"全部",v:""}),e.OptionList.forEach(t=>{"全部"!==t.Option&&o.push({n:t.Option,v:t.Option})}),r=""),t.push({key:n,name:e.Class,value:o,init:r})}}t.length>0&&(r[e]=t)}}catch(t){}});return await Promise.all(a),JSON.stringify({class:e,filters:r})}async function s(){const t=f(`${n}/home`),e=await req(t,{headers:o}),r=JSON.parse(e.content);let a=[];if(r&&Array.isArray(r))for(const t of r){const e=t.VodList||[];for(const t of e)a.push({vod_id:l(t.DId||t.DuId),vod_name:t.Name,vod_pic:l(t.TnId),vod_remarks:t.Tag})}return JSON.stringify({list:a})}async function i(t,e,r,a){const s=new Array(12).fill("");s[0]=t,s[1]=a.area||"",s[2]=a.sort||"时间",s[3]=a.class||"",s[4]=a.lang||"",s[5]=a.letter||"",s[6]=a.scat||"",s[8]="1"===e.toString()?"":e,s[11]=a.year||"";const i=f(`${n}/vodshow/${s.join("-")}`),c=await req(i,{headers:o}),p=JSON.parse(c.content);let d=[];if(p.VodList)for(const t of p.VodList)d.push({vod_id:l(t.DId||t.DuId),vod_name:t.Name,vod_pic:l(t.TnId),vod_remarks:t.Tag});let u=0;try{if(p.PaginationList){for(const t of p.PaginationList)if("StartEnd"===t.Type){const e=l(t.PId||t.PuId).split("-");if(e.length>8){const t=parseInt(e[8]);t&&(u=t)}}if(0===u)for(const t of p.PaginationList)if("ShortPage"===t.Type){const e=t.Name.split("/");if(e.length>1){const t=parseInt(e[1]);t&&(u=t)}}}}catch(t){u=1}return 0===u&&(u=1),JSON.stringify({list:d,page:parseInt(e),pagecount:u})}async function c(t,e,r=1){let a=f(`${n}/vodsearch`);a+=`&wd=${encodeURIComponent(t)}`;const s=await req(a,{headers:o}),i=JSON.parse(s.content);let c=[];if(i&&Array.isArray(i))for(const t of i)c.push({vod_id:l(t.DId||t.DuId),vod_name:t.Name,vod_pic:l(t.TnId),vod_remarks:t.Tag,vod_actor:t.Actor,vod_score:t.Rating});return JSON.stringify({list:c,page:parseInt(r)})}async function p(t){const e=f(`${n}${t}`),r=await req(e,{headers:o}),a=JSON.parse(r.content);let s=[];a.Playlist&&(s=a.Playlist.map(t=>`${t.EpisodeName}$${l(t.VId)}`));const i={vod_id:t,vod_name:a.Name,vod_pic:l(a.TnId),vod_remarks:`评分:${a.Rating}`,vod_year:a.ReleaseYear,vod_area:a.Region,vod_actor:Array.isArray(a.Actor)?a.Actor.join(","):a.Actor,vod_director:a.Director,vod_content:a.Description,vod_play_from:"独播库",vod_play_url:s.join("#"),type_name:`${a.Genre},${a.Scenario},${a.Language}`};return JSON.stringify({list:[i]})}async function d(t,e,r){const a=f(`${n}${e}`),s=await req(a,{headers:o}),i=l(JSON.parse(s.content).HId);return JSON.stringify({jx:0,parse:0,url:i,header:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36","Accept-Encoding":"gzip, deflate",origin:"https://w.duboku.io",referer:"https://w.duboku.io/",priority:"u=1, i"}})}function l(e){if(!e||"string"!=typeof e)return"";let n=e.replace(/['"]/g,"");if(!n)return"";let o="";for(let t=0;t<n.length;t+=10){o+=n.substring(t,t+10).split("").reverse().join("")}o=o.replace(/\./g,"=");try{const e=t.enc.Base64.parse(o);return t.enc.Utf8.stringify(e)}catch(t){return""}}function f(e){const n=Math.floor(800000001*Math.random()),o=function(t,e){let n=[];const o=Math.min(t.length,e.length);for(let r=0;r<o;r++)n.push(t[r]),n.push(e[r]);return n.push(t.substring(o)),n.push(e.substring(o)),n.join("")}(`${n+1e8}${9e8-n}`,Math.floor(Date.now()/1e3).toString()),r=t.enc.Utf8.parse(o),a=t.enc.Base64.stringify(r).replace(/=/g,".");return`${e}?sign=${u(60)}&token=${u(38)}&ssid=${a}`}function u(t){const e="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";let n="";for(let o=0;o<t;o++)n+=e.charAt(Math.floor(62*Math.random()));return n}export function __jsEvalReturn(){return{init:r,home:a,homeVod:s,category:i,search:c,detail:p,play:d}}
-3108
View File
File diff suppressed because it is too large. Load diff
-833
View File
@@ -1,833 +0,0 @@
import { Crypto, _ } from 'assets://js/lib/cat.js';
let siteUrl = '';
let key = '';
let iv = '';
let siteKey = '';
let siteType = 3;
let apiPrefix = 'getappapi.index';
const prefixMap = {
'1': 'getappapi.index',
'2': 'qijiappapi.index',
'3': 'appapi'
};
let enableVerifyTimeSign = false;
let headers = {
'User-Agent': 'okhttp/3.10.0',
'app-user-device-id': '291b226282010337c9443590d6457be15',
'app-version-code': '112'
};
let parseMap = {};
let homeVods = [];
let Searchstatus = false;
let searchApiSuffix = '';
let souParamName = '';
let souSalt = '';
let extraSearchHeaders = {};
let initSuffix = 'init';
let hasCustomInit = false;
let thirdDanmuBaseUrl = '';
let customPlayUa = ''; // 新增:自定义播放链接UA
let request = async (reqUrl, data, header, method) => {
let finalHeaders = { ...headers };
if (enableVerifyTimeSign) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const sign = aesEncode(timestamp, key, iv);
finalHeaders['app-api-verify-time'] = timestamp;
finalHeaders['app-api-verify-sign'] = sign;
}
if (header) {
finalHeaders = { ...finalHeaders, ...header };
}
let res = await req(reqUrl, {
method: method || 'get',
data: data || '',
headers: finalHeaders,
postType: method === 'post' ? 'form' : '',
timeout: 10000,
});
return res.content;
};
let request_text = async (reqUrl, data, header, method, tobase64) => {
let finalHeaders = { ...headers };
if (enableVerifyTimeSign) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const sign = aesEncode(timestamp, key, iv);
finalHeaders['app-api-verify-time'] = timestamp;
finalHeaders['app-api-verify-sign'] = sign;
}
if (header) {
finalHeaders = { ...finalHeaders, ...header };
}
let optObj = {
headers: finalHeaders,
method: method || 'get',
data: method === 'post' ? data : undefined,
postType: method === 'post' ? (data ? 'raw' : 'form') : undefined,
timeout: 10000,
};
if (tobase64) {
optObj.buffer = 2;
}
let res = await req(reqUrl, optObj);
return res.content;
};
async function init(cfg) {
siteKey = cfg.skey;
siteType = cfg.stype;
if (!cfg.ext) return;
let extObj;
if (typeof cfg.ext === 'string') {
extObj = JSON.parse(cfg.ext);
} else if (typeof cfg.ext === 'object' && cfg.ext !== null) {
extObj = cfg.ext;
} else {
return;
}
if (extObj.init && typeof extObj.init === 'string' && extObj.init.startsWith('V')) {
initSuffix = 'init' + extObj.init;
hasCustomInit = true;
}
if (extObj.time !== undefined) {
const timeVal = String(extObj.time);
enableVerifyTimeSign = (timeVal === '1' || timeVal === 'true' || timeVal === '1');
}
if (extObj.code !== undefined) {
forceVerifyCode = String(extObj.code).trim();
}
// 新增:读取自定义播放UA
if (extObj.ua2 !== undefined) {
customPlayUa = String(extObj.ua2).trim();
}
if (extObj.head && typeof extObj.head === 'string') {
const headStr = extObj.head.trim();
if (headStr) {
const items = headStr.split(',');
for (let item of items) {
const trimmed = item.trim();
if (!trimmed) continue;
const colonIndex = trimmed.indexOf(':');
if (colonIndex > 0) {
const hKey = trimmed.substring(0, colonIndex).trim();
const hValue = trimmed.substring(colonIndex + 1).trim();
if (hKey && hValue) {
headers[hKey] = hValue;
}
}
}
}
}
let host = extObj.host || '';
if (host) {
if (host.startsWith('http') && (host.endsWith('.txt') || host.endsWith('.json'))) {
let response = await request(host, null, headers, 'get');
let urls = response.split('\n').map(line => line.trim()).filter(line => line && line.startsWith('http'));
if (urls.length > 0) {
host = urls[0];
}
}
siteUrl = host.replace(/\/+$/, '');
if (!siteUrl.includes('php')) {
siteUrl += '/api.php';
}
}
key = extObj.key || '';
iv = extObj.iv || key;
if (extObj.api && prefixMap[extObj.api]) {
apiPrefix = prefixMap[extObj.api];
}
if (extObj.version) {
headers['app-version-code'] = String(extObj.version);
}
if (extObj.id) {
headers['app-user-device-id'] = extObj.id;
}
if (extObj.token) {
headers['app-user-token'] = extObj.token;
}
if (extObj.ua) {
headers['User-Agent'] = extObj.ua;
}
}
function processSignatureValue(sig) {
if (sig.length < 8) {
return sig.split('').reverse().join('');
} else {
let rear = sig.slice(-8).split('').reverse().join('');
let front = sig.slice(0, -8).split('').reverse().join('');
return front + rear;
}
}
async function home(filter) {
let initUrl = `${siteUrl}/${apiPrefix}/${initSuffix}`;
let rets = JSON.parse(await request(initUrl)).data;
let data = JSON.parse(aesDecode(rets, key, iv));
let rawDanmuUrl = data.config?.third_danmu_url || '';
if (Array.isArray(rawDanmuUrl)) {
rawDanmuUrl = rawDanmuUrl.find(u => u && typeof u === 'string' && u.trim()) || '';
} else if (typeof rawDanmuUrl !== 'string') {
rawDanmuUrl = '';
}
if (rawDanmuUrl) {
thirdDanmuBaseUrl = rawDanmuUrl.trim();
let lower = thirdDanmuBaseUrl.toLowerCase();
if (!lower.match(/[?&]url=$/)) {
thirdDanmuBaseUrl += thirdDanmuBaseUrl.includes('?') ? '&url=' : '?url=';
}
} else {
thirdDanmuBaseUrl = 'https://dmku.hls.one/?ac=dm&url=';
}
if (data.box_config) {
let originalKey = key;
let swappedKey = originalKey.split('').reverse().join('');
let md5Key = md5(swappedKey);
let dynamicIv = md5Key.substring(0, 16);
let decrypted = aesDecode(data.box_config, swappedKey, dynamicIv);
let boxJson = JSON.parse(decrypted);
if (boxJson.search_name) {
searchApiSuffix = boxJson.search_name;
}
if (boxJson.signature_name && boxJson.signature_value) {
souParamName = boxJson.signature_name;
souSalt = processSignatureValue(boxJson.signature_value);
}
if (boxJson.api_header && boxJson.api_header.key && boxJson.api_header.value) {
extraSearchHeaders[boxJson.api_header.key] = boxJson.api_header.value;
}
} else {
searchApiSuffix = 'searchList';
souParamName = '';
souSalt = '';
}
Searchstatus = data.config?.system_search_verify_status || false;
let filters = {};
let classes = [];
homeVods = [];
_.forEach(data.type_list, item => {
if (item.type_id > 0) {
if (item.recommend_list && Array.isArray(item.recommend_list)) {
homeVods = homeVods.concat(item.recommend_list);
}
}
classes.push({
type_id: item.type_id,
type_name: item.type_name,
});
let filterList = [];
_.forEach(item.filter_type_list, f => {
let filter = {};
if (f.name === 'class') {
filter['name'] = '分类';
filter['key'] = f.name;
filter['value'] = _.map(f.list, i => ({ v: i, n: i }));
}
if (f.name === 'area') {
filter['name'] = '区域';
filter['key'] = f.name;
filter['value'] = _.map(f.list, i => ({ v: i, n: i }));
}
if (f.name === 'lang') {
filter['name'] = '语言';
filter['key'] = f.name;
filter['value'] = _.map(f.list, i => ({ v: i, n: i }));
}
if (f.name === 'year') {
filter['name'] = '年份';
filter['key'] = f.name;
filter['value'] = _.map(f.list, i => ({ v: i, n: i }));
}
if (f.name === 'sort') {
filter['name'] = '排序';
filter['key'] = f.name;
filter['value'] = _.map(f.list, i => ({ v: i, n: i }));
}
if (Object.keys(filter).length > 0) {
filterList.push(filter);
}
});
if (filterList.length > 0) {
filters[item.type_id] = filterList;
}
});
return JSON.stringify({
'class': classes,
'filters': filters,
});
}
async function homeVod() {
return JSON.stringify({
list: homeVods,
});
}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
let url = `${siteUrl}/${apiPrefix}/typeFilterVodList`;
let params = {
"area": extend['area'] || "全部",
"sort": extend['sort'] || "最新",
"class": extend['class'] || "全部",
"type_id": tid,
"year": extend['year'] || "全部",
"lang": extend['lang'] || '全部',
"page": pg,
};
let encData = JSON.parse(await request(url, params, '', 'post')).data;
let videos = JSON.parse(aesDecode(encData, key, iv)).recommend_list;
return JSON.stringify({
page: pg,
pagecount: 9999,
list: videos,
});
}
async function detail(id) {
let url = `${siteUrl}/${apiPrefix}/vodDetail`;
let resp = await request(url, { vod_id: id }, '', 'post');
let jsonResp = JSON.parse(resp);
let encData = jsonResp.data;
let decoded = aesDecode(encData, key, iv);
let info = JSON.parse(decoded);
let videos = {
vod_id: info.vod.vod_id,
vod_name: info.vod.vod_name,
vod_area: info.vod.vod_area,
vod_director: info.vod.vod_director,
vod_actor: info.vod.vod_actor,
vod_pic: info.vod.vod_pic,
vod_content: info.vod.vod_content,
type_name: info.vod.vod_class,
vod_year: info.vod.vod_year
};
let froms = [];
let urls = [];
let playSources = _.map(info.vod_play_list, item => {
const playerInfo = item.player_info || {};
const parse = playerInfo.parse || '';
const ua = playerInfo.user_agent || customPlayUa || ''; // 修改:优先使用自定义UA,如果没有则使用原有的
const nameUrls = _.map(item.urls || [], item2 => {
const { name = '', url = '', token = '', parse_api_url = '', nid = 1 } = item2;
return `${name}$${url}@@${parse}@@${token}@@${parse_api_url}@@${ua}@@${info.vod.vod_id}@@${nid}`;
}).join('#');
return {
show: playerInfo.show || 'Unknown',
urls: nameUrls
};
});
let showCount = {};
playSources = _.map(playSources, source => {
let showName = source.show;
if (showCount[showName]) {
showCount[showName]++;
showName = `${showName}${showCount[showName]}`;
} else {
showCount[showName] = 1;
}
return {
show: showName,
urls: source.urls
};
});
playSources.sort((a, b) => {
const aShow = a.show.toLowerCase();
const bShow = b.show.toLowerCase();
const getPriority = (show) => {
if (show.includes('4k')) return 1;
if (show.includes('K')) return 2;
if (show.includes('独家')) return 3;
if (show.includes('秒播')) return 4;
if (show.includes('自建')) return 5;
if (show.includes('蓝光')) return 6;
if (show.includes('专线')) return 7;
return 8;
};
return getPriority(aShow) - getPriority(bShow);
});
froms = _.map(playSources, source => source.show);
urls = _.map(playSources, source => source.urls);
videos.vod_play_from = froms.join('$$$');
videos.vod_play_url = urls.join('$$$');
return JSON.stringify({
list: [videos],
});
}
async function play(flag, id, flags) {
let parts = id.split('@@');
let playUrl = parts[0];
let parse = parts[1] || '';
let token = parts[2] || '';
let parse_api_url = parts[3] || '';
let ua = parts[4] || ''; // 新增:获取UA
let vodId = parts[5] || '';
let nidStr = parts[6] || '1';
let danmakuUrl = '';
if (thirdDanmuBaseUrl && vodId) {
let nid = parseInt(nidStr, 10);
if (isNaN(nid) || nid < 1) nid = 1;
let urlPosition = nid - 1;
let danmuParams = {
url_position: urlPosition.toString(),
vod_id: vodId
};
let danmuRet = await request(`${siteUrl}/${apiPrefix}/danmuList`, danmuParams, '', 'post');
let danmuResponse = JSON.parse(danmuRet);
if (danmuResponse.data) {
let decryptedDanmu = JSON.parse(aesDecode(danmuResponse.data, key, iv));
if (decryptedDanmu && decryptedDanmu.official_url) {
let realDanmuUrl = thirdDanmuBaseUrl + decryptedDanmu.official_url;
let EncodedUrl = encodeURIComponent(realDanmuUrl);
let headerJson = JSON.stringify(headers);
danmakuUrl = js2Proxy(
false,
siteType,
siteKey || '',
EncodedUrl,
headers
);
}
}
}
// 修改:如果存在自定义UA,添加到返回参数中
if (
(playUrl.includes('http://') || playUrl.includes('https://')) &&
(playUrl.includes('m3u8') || playUrl.includes('mp4') || playUrl.includes('mkv')) &&
!parse_api_url
) {
let result = {
parse: 0,
url: playUrl,
danmaku: danmakuUrl
};
// 如果存在自定义UA,添加到返回结果中
if (ua) {
result.header = { 'User-Agent': ua };
}
return JSON.stringify(result);
}
if (parse.startsWith("http")) {
let parseUrl = parse + playUrl;
if (token) {
parseUrl += '&token=' + token;
}
// 如果存在自定义UA,在请求解析接口时使用
let requestHeaders = {};
if (ua) {
requestHeaders['User-Agent'] = ua;
}
let rets = await request(parseUrl, null, requestHeaders, 'get');
if (rets.indexOf('DOCTYPE html') > -1) {
let result = {
parse: 1,
url: parseUrl,
danmaku: danmakuUrl
};
if (ua) {
result.header = { 'User-Agent': ua };
}
return JSON.stringify(result);
}
let parseJson = JSON.parse(rets);
let result = {
parse: 0,
url: parseJson['url'] || parseJson['data']['url'] || '',
danmaku: danmakuUrl
};
// 如果存在自定义UA,添加到返回结果中
if (ua) {
result.header = { 'User-Agent': ua };
}
return JSON.stringify(result);
}
let params = {
'parse_api': parse,
'url': aesEncode(playUrl, key, iv),
'token': token,
};
// 如果存在自定义UA,在请求时使用
let requestHeaders = {};
if (ua) {
requestHeaders['User-Agent'] = ua;
}
let rets = await request(`${siteUrl}/${apiPrefix}/vodParse`, params, requestHeaders, 'post');
let urlDecoded = aesDecode(JSON.parse(rets).data, key, iv);
let finalPlayUrl = '';
let parsed = JSON.parse(urlDecoded);
finalPlayUrl = JSON.parse(parsed.json).url || '';
let result = {
parse: 0,
url: finalPlayUrl,
danmaku: danmakuUrl
};
// 如果存在自定义UA,添加到返回结果中
if (ua) {
result.header = { 'User-Agent': ua };
}
return JSON.stringify(result);
}
async function search(wd, quick, pg) {
if (hasCustomInit) {
await home({});
}
let searchPath = searchApiSuffix || 'searchList';
let url = `${siteUrl}/${apiPrefix}/${searchPath}`;
let retryCount = 0;
const maxRetries = 1;
let videos = [];
let attemptedCaptcha = false;
let attemptedSlider = false;
let sliderVerified = false;
let sliderId = '';
let params = {
'page': '1',
'type_id': '0',
'keywords': wd,
};
if (souParamName && souSalt) {
const currentTimestamp = Math.floor(Date.now() / 1000).toString();
const souString = `/${souParamName}-${currentTimestamp}-sb-0-${souSalt}`;
const md5Value = md5(souString);
const finalValue = `${currentTimestamp}-sb-0-${md5Value}`;
params[souParamName] = finalValue;
}
let searchHeaders = { ...headers, ...extraSearchHeaders };
if (forceVerifyCode) {
params['code'] = forceVerifyCode;
const random_uuid = generateUUID();
params['key'] = random_uuid;
}
const maxWaitRetries = 2;
let waitRetryCount = 0;
while (true) {
let encData = await request(url, params, searchHeaders, 'post');
let response = JSON.parse(encData);
if (response.code === 1001 && response.need_slider === true && !attemptedSlider) {
attemptedSlider = true;
let getSliderUrl = `${siteUrl}/${apiPrefix}/getSlider`;
let sliderResponse = await request(getSliderUrl, {}, searchHeaders, 'post');
let sliderJson = JSON.parse(sliderResponse);
if (sliderJson.code === 1 && sliderJson.data) {
let sliderDecrypted = aesDecode(sliderJson.data, key, iv);
let sliderData = JSON.parse(sliderDecrypted);
sliderId = sliderData.slider_id || '';
let targetX = parseInt(sliderData.target_x) || 0;
let targetY = parseInt(sliderData.target_y) || 0;
if (sliderId && targetX > 0) {
let posX = targetX;
if (targetX > 0) {
let randomOffset = Math.floor(Math.random() * 3) - 1;
posX = targetX + randomOffset;
if (posX < 1) posX = 1;
if (posX > (sliderData.bg_width || 280)) posX = sliderData.bg_width || 280;
}
let timestamp = Date.now();
await new Promise(resolve => setTimeout(resolve, 1000));
let verifyParams = {
pos_x: posX.toString(),
slider_id: sliderId,
timestamp: timestamp.toString()
};
let verifySliderUrl = `${siteUrl}/${apiPrefix}/verifySlider`;
let verifyResponse = await request(verifySliderUrl, verifyParams, searchHeaders, 'post');
let verifyJson = JSON.parse(verifyResponse);
if (verifyJson.code === 1 && verifyJson.data) {
let verifyDecrypted = aesDecode(verifyJson.data, key, iv);
let verifyResult = JSON.parse(verifyDecrypted);
if (verifyResult.verified === true) {
sliderVerified = true;
continue;
}
}
}
}
if (!sliderVerified) {
if (!forceVerifyCode && (Searchstatus || (response.code === 0 && response.msg && response.msg.includes('验证码')))) {
if (attemptedCaptcha) break;
attemptedCaptcha = true;
const random_uuid = generateUUID();
let modifiedApiPrefix = apiPrefix.replace('.index', '');
let verifyUrl = `${siteUrl}/${modifiedApiPrefix}.verify/create?key=${random_uuid}`;
let base64Img = await request_text(verifyUrl, null, headers, 'get', true);
base64Img = base64Img.replace(/\n/g, '');
let ocrResult = await request_text('https://api.nn.ci/ocr/b64/text', base64Img, { 'User-Agent': 'okhttp/3.10.0' }, 'post');
params['code'] = ocrResult.trim();
params['key'] = random_uuid;
retryCount++;
continue;
} else {
break;
}
}
}
if (response.code === 0 &&
(!response.data || response.data.length === 0) &&
response.msg &&
/等.*秒|等待.*秒|等|搜|请等待|稍等|稍候/i.test(response.msg)) {
if (waitRetryCount >= maxWaitRetries) break;
let waitSeconds = extractWaitTime(response.msg);
if (waitSeconds < 1) waitSeconds = 2;
if (waitSeconds > 30) waitSeconds = 30;
const actualWait = waitSeconds + 1;
await new Promise(resolve => setTimeout(resolve, actualWait * 1000));
waitRetryCount++;
continue;
}
if (response.data && response.data.length > 0) {
let decodedData = JSON.parse(aesDecode(response.data, key, iv));
videos = decodedData.search_list || [];
break;
} else if (!forceVerifyCode && (Searchstatus || (response.code === 0 && response.msg && response.msg.includes('验证码')))) {
if (attemptedCaptcha) break;
attemptedCaptcha = true;
const random_uuid = generateUUID();
let modifiedApiPrefix = apiPrefix.replace('.index', '');
let verifyUrl = `${siteUrl}/${modifiedApiPrefix}.verify/create?key=${random_uuid}`;
let base64Img = await request_text(verifyUrl, null, headers, 'get', true);
base64Img = base64Img.replace(/\n/g, '');
let ocrResult = await request_text('https://api.nn.ci/ocr/b64/text', base64Img, { 'User-Agent': 'okhttp/3.10.0' }, 'post');
params['code'] = ocrResult.trim();
params['key'] = random_uuid;
retryCount++;
continue;
} else {
break;
}
}
return JSON.stringify({
list: videos,
});
}
function generateUUID() {
const chars = '0123456789abcdef';
const uuidTemplate = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
return uuidTemplate.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return chars[v];
});
}
function aesDecode(str, keyStr, ivStr, type) {
const key = Crypto.enc.Utf8.parse(keyStr);
if (type === 'hex') {
str = Crypto.enc.Hex.parse(str);
return Crypto.AES.decrypt({
ciphertext: str
}, key, {
iv: Crypto.enc.Utf8.parse(ivStr),
mode: Crypto.mode.CBC,
padding: Crypto.pad.Pkcs7
}).toString(Crypto.enc.Utf8);
} else {
return Crypto.AES.decrypt(str, key, {
iv: Crypto.enc.Utf8.parse(ivStr),
mode: Crypto.mode.CBC,
padding: Crypto.pad.Pkcs7
}).toString(Crypto.enc.Utf8);
}
}
function aesEncode(str, keyStr, ivStr, type) {
const key = Crypto.enc.Utf8.parse(keyStr);
let encData = Crypto.AES.encrypt(str, key, {
iv: Crypto.enc.Utf8.parse(ivStr),
mode: Crypto.mode.CBC,
padding: Crypto.pad.Pkcs7
});
if (type === 'hex') return encData.ciphertext.toString(Crypto.enc.Hex);
return encData.toString();
}
function md5(text) {
return Crypto.MD5(text).toString();
}
function chineseToNumber(chineseStr) {
const chineseNumMap = {
'零': 0, '〇': 0, '一': 1, '壹': 1, '二': 2, '贰': 2, '两': 2,
'三': 3, '叁': 3, '四': 4, '肆': 4, '五': 5, '伍': 5,
'六': 6, '陆': 6, '七': 7, '柒': 7, '八': 8, '捌': 8,
'九': 9, '玖': 9, '十': 10, '拾': 10
};
if (chineseStr.length === 1) {
return chineseNumMap[chineseStr] || 2;
}
if (chineseStr.startsWith('十') && chineseStr.length === 2) {
const units = chineseNumMap[chineseStr[1]];
return units ? 10 + units : 10;
}
if (chineseStr.endsWith('十') && chineseStr.length === 2) {
const tens = chineseNumMap[chineseStr[0]];
return tens ? tens * 10 : 10;
}
if (chineseStr.length === 3 && chineseStr.includes('十')) {
const tens = chineseNumMap[chineseStr[0]];
const units = chineseNumMap[chineseStr[2]];
return tens && units ? tens * 10 + units : (tens ? tens * 10 : 10);
}
return 2;
}
function extractWaitTime(message) {
const digitMatch = message.match(/(\d+)\s*秒/);
if (digitMatch && digitMatch[1]) {
return parseInt(digitMatch[1], 10);
}
const chineseMatch = message.match(/([零一二三四五六七八九十两壹贰叁肆伍陆柒捌玖拾〇]+)\s*秒/);
if (chineseMatch && chineseMatch[1]) {
return chineseToNumber(chineseMatch[1]);
}
if (/几秒|数秒|若干秒/i.test(message)) {
return 3;
}
return 2;
}
function hexToDec(hex) {
hex = (hex || '#FFFFFF').replace(/^#/, '').toUpperCase();
if (hex.length !== 6) {
while (hex.length < 6) hex += '0';
hex = hex.slice(0, 6);
}
return parseInt(hex, 16);
}
function escapeXml(str) {
if (typeof str !== 'string') return '';
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&apos;');
}
function jsonDanmakuToXml(json) {
if (!json || !json.danmuku || !Array.isArray(json.danmuku)) {
return '<?xml version="1.0" encoding="utf-8"?><i><code>0</code><id>error_no_danmaku</id></i>';
}
let lines = [];
lines.push('<?xml version="1.0" encoding="utf-8"?>');
lines.push('<i>');
lines.push(` <code>${json.code || 0}</code>`);
lines.push(` <id>${escapeXml(json.name || '12345')}</id>`);
const positionMap = {
'top': 5,
'right': 1,
'bottom': 4,
'left': 6,
'scroll': 1
};
json.danmuku.forEach(danmu => {
if (!Array.isArray(danmu) || danmu.length < 5) return;
let [
time = 0,
mode = 'scroll',
colorHex = '#FFFFFF',
,
text = '',
, ,
fontSize = "24px"
] = danmu;
colorHex = '#' + Array(6).fill(0).map(() => '0123456789ABCDEF'[Math.floor(Math.random() * 16)]).join('');
let pos = positionMap[mode] || 1;
let colorDec = hexToDec(colorHex);
let fs = parseInt(String(fontSize).replace(/px/gi, '')) || 24;
let p = `${Number(time).toFixed(3)},${pos},${fs},${colorDec},,,,,`;
let safeText = escapeXml(text);
lines.push(` <d p="${p}">${safeText}</d>`);
});
lines.push('</i>');
return lines.join('\n');
}
async function proxy(params) {
let jsonUrl = decodeURIComponent(
params.url || params[0] || params.danmaku || '' || ''
);
if (!jsonUrl || !jsonUrl.startsWith('http')) {
return JSON.stringify({
code: 400,
content: "缺少有效的弹幕 URL",
headers: { "Content-Type": "text/plain" }
});
}
let jsonContent = await request_text(jsonUrl, null, headers, 'get');
let jsonObj = JSON.parse(jsonContent);
let xmlContent = jsonDanmakuToXml(jsonObj);
return JSON.stringify({
code: 200,
content: xmlContent,
headers: {
"Content-Type": "text/xml; charset=utf-8",
"Cache-Control": "no-cache"
}
});
}
let forceVerifyCode = null;
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
proxy: proxy
};
}
-607
View File
@@ -1,607 +0,0 @@
/*!
* Jinja Templating for JavaScript v0.1.8
* https://github.com/sstur/jinja-js
*
* This is a slimmed-down Jinja2 implementation [http://jinja.pocoo.org/]
*
* In the interest of simplicity, it deviates from Jinja2 as follows:
* - Line statements, cycle, super, macro tags and block nesting are not implemented
* - auto escapes html by default (the filter is "html" not "e")
* - Only "html" and "safe" filters are built in
* - Filters are not valid in expressions; `foo|length > 1` is not valid
* - Expression Tests (`if num is odd`) not implemented (`is` translates to `==` and `isnot` to `!=`)
*
* Notes:
* - if property is not found, but method '_get' exists, it will be called with the property name (and cached)
* - `{% for n in obj %}` iterates the object's keys; get the value with `{% for n in obj %}{{ obj[n] }}{% endfor %}`
* - subscript notation `a[0]` takes literals or simple variables but not `a[item.key]`
* - `.2` is not a valid number literal; use `0.2`
*
*/
/*global require, exports, module, define */
(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.jinja = {}));
})(this, (function(jinja) {
"use strict";
var STRINGS = /'(\\.|[^'])*'|"(\\.|[^"'"])*"/g;
var IDENTS_AND_NUMS = /([$_a-z][$\w]*)|([+-]?\d+(\.\d+)?)/g;
var NUMBER = /^[+-]?\d+(\.\d+)?$/;
//non-primitive literals (array and object literals)
var NON_PRIMITIVES = /\[[@#~](,[@#~])*\]|\[\]|\{([@i]:[@#~])(,[@i]:[@#~])*\}|\{\}/g;
//bare identifiers such as variables and in object literals: {foo: 'value'}
var IDENTIFIERS = /[$_a-z][$\w]*/ig;
var VARIABLES = /i(\.i|\[[@#i]\])*/g;
var ACCESSOR = /(\.i|\[[@#i]\])/g;
var OPERATORS = /(===?|!==?|>=?|<=?|&&|\|\||[+\-\*\/%])/g;
//extended (english) operators
var EOPS = /(^|[^$\w])(and|or|not|is|isnot)([^$\w]|$)/g;
var LEADING_SPACE = /^\s+/;
var TRAILING_SPACE = /\s+$/;
var START_TOKEN = /\{\{\{|\{\{|\{%|\{#/;
var TAGS = {
'{{{': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}\}/,
'{{': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?\}\}/,
'{%': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?%\}/,
'{#': /^('(\\.|[^'])*'|"(\\.|[^"'"])*"|.)+?#\}/
};
var delimeters = {
'{%': 'directive',
'{{': 'output',
'{#': 'comment'
};
var operators = {
and: '&&',
or: '||',
not: '!',
is: '==',
isnot: '!='
};
var constants = {
'true': true,
'false': false,
'null': null
};
function Parser() {
this.nest = [];
this.compiled = [];
this.childBlocks = 0;
this.parentBlocks = 0;
this.isSilent = false;
}
Parser.prototype.push = function(line) {
if (!this.isSilent) {
this.compiled.push(line);
}
};
Parser.prototype.parse = function(src) {
this.tokenize(src);
return this.compiled;
};
Parser.prototype.tokenize = function(src) {
var lastEnd = 0,
parser = this,
trimLeading = false;
matchAll(src, START_TOKEN, function(open, index, src) {
//here we match the rest of the src against a regex for this tag
var match = src.slice(index + open.length).match(TAGS[open]);
match = (match ? match[0] : '');
//here we sub out strings so we don't get false matches
var simplified = match.replace(STRINGS, '@');
//if we don't have a close tag or there is a nested open tag
if (!match || ~simplified.indexOf(open)) {
return index + 1;
}
var inner = match.slice(0, 0 - open.length);
//check for white-space collapse syntax
if (inner.charAt(0) === '-') var wsCollapseLeft = true;
if (inner.slice(-1) === '-') var wsCollapseRight = true;
inner = inner.replace(/^-|-$/g, '').trim();
//if we're in raw mode and we are not looking at an "endraw" tag, move along
if (parser.rawMode && (open + inner) !== '{%endraw') {
return index + 1;
}
var text = src.slice(lastEnd, index);
lastEnd = index + open.length + match.length;
if (trimLeading) text = trimLeft(text);
if (wsCollapseLeft) text = trimRight(text);
if (wsCollapseRight) trimLeading = true;
if (open === '{{{') {
//liquid-style: make {{{x}}} => {{x|safe}}
open = '{{';
inner += '|safe';
}
parser.textHandler(text);
parser.tokenHandler(open, inner);
});
var text = src.slice(lastEnd);
if (trimLeading) text = trimLeft(text);
this.textHandler(text);
};
Parser.prototype.textHandler = function(text) {
this.push('write(' + JSON.stringify(text) + ');');
};
Parser.prototype.tokenHandler = function(open, inner) {
var type = delimeters[open];
if (type === 'directive') {
this.compileTag(inner);
} else if (type === 'output') {
var extracted = this.extractEnt(inner, STRINGS, '@');
//replace || operators with ~
extracted.src = extracted.src.replace(/\|\|/g, '~').split('|');
//put back || operators
extracted.src = extracted.src.map(function(part) {
return part.split('~').join('||');
});
var parts = this.injectEnt(extracted, '@');
if (parts.length > 1) {
var filters = parts.slice(1).map(this.parseFilter.bind(this));
this.push('filter(' + this.parseExpr(parts[0]) + ',' + filters.join(',') + ');');
} else {
this.push('filter(' + this.parseExpr(parts[0]) + ');');
}
}
};
Parser.prototype.compileTag = function(str) {
var directive = str.split(' ')[0];
var handler = tagHandlers[directive];
if (!handler) {
throw new Error('Invalid tag: ' + str);
}
handler.call(this, str.slice(directive.length).trim());
};
Parser.prototype.parseFilter = function(src) {
src = src.trim();
var match = src.match(/[:(]/);
var i = match ? match.index : -1;
if (i < 0) return JSON.stringify([src]);
var name = src.slice(0, i);
var args = src.charAt(i) === ':' ? src.slice(i + 1) : src.slice(i + 1, -1);
args = this.parseExpr(args, {
terms: true
});
return '[' + JSON.stringify(name) + ',' + args + ']';
};
Parser.prototype.extractEnt = function(src, regex, placeholder) {
var subs = [],
isFunc = typeof placeholder == 'function';
src = src.replace(regex, function(str) {
var replacement = isFunc ? placeholder(str) : placeholder;
if (replacement) {
subs.push(str);
return replacement;
}
return str;
});
return {
src: src,
subs: subs
};
};
Parser.prototype.injectEnt = function(extracted, placeholder) {
var src = extracted.src,
subs = extracted.subs,
isArr = Array.isArray(src);
var arr = (isArr) ? src : [src];
var re = new RegExp('[' + placeholder + ']', 'g'),
i = 0;
arr.forEach(function(src, index) {
arr[index] = src.replace(re, function() {
return subs[i++];
});
});
return isArr ? arr : arr[0];
};
//replace complex literals without mistaking subscript notation with array literals
Parser.prototype.replaceComplex = function(s) {
var parsed = this.extractEnt(s, /i(\.i|\[[@#i]\])+/g, 'v');
parsed.src = parsed.src.replace(NON_PRIMITIVES, '~');
return this.injectEnt(parsed, 'v');
};
//parse expression containing literals (including objects/arrays) and variables (including dot and subscript notation)
//valid expressions: `a + 1 > b.c or c == null`, `a and b[1] != c`, `(a < b) or (c < d and e)`, 'a || [1]`
Parser.prototype.parseExpr = function(src, opts) {
opts = opts || {};
//extract string literals -> @
var parsed1 = this.extractEnt(src, STRINGS, '@');
//note: this will catch {not: 1} and a.is; could we replace temporarily and then check adjacent chars?
parsed1.src = parsed1.src.replace(EOPS, function(s, before, op, after) {
return (op in operators) ? before + operators[op] + after : s;
});
//sub out non-string literals (numbers/true/false/null) -> #
// the distinction is necessary because @ can be object identifiers, # cannot
var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function(s) {
return (s in constants || NUMBER.test(s)) ? '#' : null;
});
//sub out object/variable identifiers -> i
var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, 'i');
//remove white-space
parsed3.src = parsed3.src.replace(/\s+/g, '');
//the rest of this is simply to boil the expression down and check validity
var simplified = parsed3.src;
//sub out complex literals (objects/arrays) -> ~
// the distinction is necessary because @ and # can be subscripts but ~ cannot
while (simplified !== (simplified = this.replaceComplex(simplified)));
//now @ represents strings, # represents other primitives and ~ represents non-primitives
//replace complex variables (those with dot/subscript accessors) -> v
while (simplified !== (simplified = simplified.replace(/i(\.i|\[[@#i]\])+/, 'v')));
//empty subscript or complex variables in subscript, are not permitted
simplified = simplified.replace(/[iv]\[v?\]/g, 'x');
//sub in "i" for @ and # and ~ and v (now "i" represents all literals, variables and identifiers)
simplified = simplified.replace(/[@#~v]/g, 'i');
//sub out operators
simplified = simplified.replace(OPERATORS, '%');
//allow 'not' unary operator
simplified = simplified.replace(/!+[i]/g, 'i');
var terms = opts.terms ? simplified.split(',') : [simplified];
terms.forEach(function(term) {
//simplify logical grouping
while (term !== (term = term.replace(/\(i(%i)*\)/g, 'i')));
if (!term.match(/^i(%i)*/)) {
throw new Error('Invalid expression: ' + src + " " + term);
}
});
parsed3.src = parsed3.src.replace(VARIABLES, this.parseVar.bind(this));
parsed2.src = this.injectEnt(parsed3, 'i');
parsed1.src = this.injectEnt(parsed2, '#');
return this.injectEnt(parsed1, '@');
};
Parser.prototype.parseVar = function(src) {
var args = Array.prototype.slice.call(arguments);
var str = args.pop(),
index = args.pop();
//quote bare object identifiers (might be a reserved word like {while: 1})
if (src === 'i' && str.charAt(index + 1) === ':') {
return '"i"';
}
var parts = ['"i"'];
src.replace(ACCESSOR, function(part) {
if (part === '.i') {
parts.push('"i"');
} else if (part === '[i]') {
parts.push('get("i")');
} else {
parts.push(part.slice(1, -1));
}
});
return 'get(' + parts.join(',') + ')';
};
//escapes a name to be used as a javascript identifier
Parser.prototype.escName = function(str) {
return str.replace(/\W/g, function(s) {
return '$' + s.charCodeAt(0).toString(16);
});
};
Parser.prototype.parseQuoted = function(str) {
if (str.charAt(0) === "'") {
str = str.slice(1, -1).replace(/\\.|"/, function(s) {
if (s === "\\'") return "'";
return s.charAt(0) === '\\' ? s : ('\\' + s);
});
str = '"' + str + '"';
}
//todo: try/catch or deal with invalid characters (linebreaks, control characters)
return JSON.parse(str);
};
//the context 'this' inside tagHandlers is the parser instance
var tagHandlers = {
'if': function(expr) {
this.push('if (' + this.parseExpr(expr) + ') {');
this.nest.unshift('if');
},
'else': function() {
if (this.nest[0] === 'for') {
this.push('}, function() {');
} else {
this.push('} else {');
}
},
'elseif': function(expr) {
this.push('} else if (' + this.parseExpr(expr) + ') {');
},
'endif': function() {
this.nest.shift();
this.push('}');
},
'for': function(str) {
var i = str.indexOf(' in ');
var name = str.slice(0, i).trim();
var expr = str.slice(i + 4).trim();
this.push('each(' + this.parseExpr(expr) + ',' + JSON.stringify(name) + ',function() {');
this.nest.unshift('for');
},
'endfor': function() {
this.nest.shift();
this.push('});');
},
'raw': function() {
this.rawMode = true;
},
'endraw': function() {
this.rawMode = false;
},
'set': function(stmt) {
var i = stmt.indexOf('=');
var name = stmt.slice(0, i).trim();
var expr = stmt.slice(i + 1).trim();
this.push('set(' + JSON.stringify(name) + ',' + this.parseExpr(expr) + ');');
},
'block': function(name) {
if (this.isParent) {
++this.parentBlocks;
var blockName = 'block_' + (this.escName(name) || this.parentBlocks);
this.push('block(typeof ' + blockName + ' == "function" ? ' + blockName + ' : function() {');
} else if (this.hasParent) {
this.isSilent = false;
++this.childBlocks;
blockName = 'block_' + (this.escName(name) || this.childBlocks);
this.push('function ' + blockName + '() {');
}
this.nest.unshift('block');
},
'endblock': function() {
this.nest.shift();
if (this.isParent) {
this.push('});');
} else if (this.hasParent) {
this.push('}');
this.isSilent = true;
}
},
'extends': function(name) {
name = this.parseQuoted(name);
var parentSrc = this.readTemplateFile(name);
this.isParent = true;
this.tokenize(parentSrc);
this.isParent = false;
this.hasParent = true;
//silence output until we enter a child block
this.isSilent = true;
},
'include': function(name) {
name = this.parseQuoted(name);
var incSrc = this.readTemplateFile(name);
this.isInclude = true;
this.tokenize(incSrc);
this.isInclude = false;
}
};
//liquid style
tagHandlers.assign = tagHandlers.set;
//python/django style
tagHandlers.elif = tagHandlers.elseif;
var getRuntime = function runtime(data, opts) {
var defaults = {
autoEscape: 'toJson'
};
var _toString = Object.prototype.toString;
var _hasOwnProperty = Object.prototype.hasOwnProperty;
var getKeys = Object.keys || function(obj) {
var keys = [];
for (var n in obj)
if (_hasOwnProperty.call(obj, n)) keys.push(n);
return keys;
};
var isArray = Array.isArray || function(obj) {
return _toString.call(obj) === '[object Array]';
};
var create = Object.create || function(obj) {
function F() {}
F.prototype = obj;
return new F();
};
var toString = function(val) {
if (val == null) return '';
return (typeof val.toString == 'function') ? val.toString() : _toString.call(val);
};
var extend = function(dest, src) {
var keys = getKeys(src);
for (var i = 0, len = keys.length; i < len; i++) {
var key = keys[i];
dest[key] = src[key];
}
return dest;
};
//get a value, lexically, starting in current context; a.b -> get("a","b")
var get = function() {
var val, n = arguments[0],
c = stack.length;
while (c--) {
val = stack[c][n];
if (typeof val != 'undefined') break;
}
for (var i = 1, len = arguments.length; i < len; i++) {
if (val == null) continue;
n = arguments[i];
val = (_hasOwnProperty.call(val, n)) ? val[n] : (typeof val._get == 'function' ? (val[n] = val._get(n)) : null);
}
return (val == null) ? '' : val;
};
var set = function(n, val) {
stack[stack.length - 1][n] = val;
};
var push = function(ctx) {
stack.push(ctx || {});
};
var pop = function() {
stack.pop();
};
var write = function(str) {
output.push(str);
};
var filter = function(val) {
for (var i = 1, len = arguments.length; i < len; i++) {
var arr = arguments[i],
name = arr[0],
filter = filters[name];
if (filter) {
arr[0] = val;
//now arr looks like [val, arg1, arg2]
val = filter.apply(data, arr);
} else {
throw new Error('Invalid filter: ' + name);
}
}
if (opts.autoEscape && name !== opts.autoEscape && name !== 'safe') {
//auto escape if not explicitly safe or already escaped
val = filters[opts.autoEscape].call(data, val);
}
output.push(val);
};
var each = function(obj, loopvar, fn1, fn2) {
if (obj == null) return;
var arr = isArray(obj) ? obj : getKeys(obj),
len = arr.length;
var ctx = {
loop: {
length: len,
first: arr[0],
last: arr[len - 1]
}
};
push(ctx);
for (var i = 0; i < len; i++) {
extend(ctx.loop, {
index: i + 1,
index0: i
});
fn1(ctx[loopvar] = arr[i]);
}
if (len === 0 && fn2) fn2();
pop();
};
var block = function(fn) {
push();
fn();
pop();
};
var render = function() {
return output.join('');
};
data = data || {};
opts = extend(defaults, opts || {});
var filters = extend({
html: function(val) {
return toString(val)
.split('&').join('&amp;')
.split('<').join('&lt;')
.split('>').join('&gt;')
.split('"').join('&quot;');
},
safe: function(val) {
return val;
},
toJson: function(val) {
if (typeof val === 'object') {
return JSON.stringify(val);
}
return toString(val);
}
}, opts.filters || {});
var stack = [create(data || {})],
output = [];
return {
get: get,
set: set,
push: push,
pop: pop,
write: write,
filter: filter,
each: each,
block: block,
render: render
};
};
var runtime;
jinja.compile = function(markup, opts) {
opts = opts || {};
var parser = new Parser();
parser.readTemplateFile = this.readTemplateFile;
var code = [];
code.push('function render($) {');
code.push('var get = $.get, set = $.set, push = $.push, pop = $.pop, write = $.write, filter = $.filter, each = $.each, block = $.block;');
code.push.apply(code, parser.parse(markup));
code.push('return $.render();');
code.push('}');
code = code.join('\n');
if (opts.runtime === false) {
var fn = new Function('data', 'options', 'return (' + code + ')(runtime(data, options))');
} else {
runtime = runtime || (runtime = getRuntime.toString());
fn = new Function('data', 'options', 'return (' + code + ')((' + runtime + ')(data, options))');
}
return {
render: fn
};
};
jinja.render = function(markup, data, opts) {
var tmpl = jinja.compile(markup);
return tmpl.render(data, opts);
};
jinja.templateFiles = [];
jinja.readTemplateFile = function(name) {
var templateFiles = this.templateFiles || [];
var templateFile = templateFiles[name];
if (templateFile == null) {
throw new Error('Template file not found: ' + name);
}
return templateFile;
};
/*!
* Helpers
*/
function trimLeft(str) {
return str.replace(LEADING_SPACE, '');
}
function trimRight(str) {
return str.replace(TRAILING_SPACE, '');
}
function matchAll(str, reg, fn) {
//copy as global
reg = new RegExp(reg.source, 'g' + (reg.ignoreCase ? 'i' : '') + (reg.multiline ? 'm' : ''));
var match;
while ((match = reg.exec(str))) {
var result = fn(match[0], match.index, str);
if (typeof result == 'number') {
reg.lastIndex = result;
}
}
}
}));
-360
View File
@@ -1,360 +0,0 @@
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object') {
// CommonJS
module.exports = exports = factory();
} else if (typeof define === 'function' && define.amd) {
// AMD
define([], factory);
} else {
// Global (browser)
globalThis.JSEncrypt = factory();
}
})(this, () => {
return /******/ (() => { // webpackBootstrap
/******/
var __webpack_modules__ = ({
/***/
"./lib/JSEncrypt.js":
/*!**************************!*\
!*** ./lib/JSEncrypt.js ***!
\**************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JSEncrypt\": () => (/* binding */ JSEncrypt)\n/* harmony export */ });\n/* harmony import */ var _lib_jsbn_base64__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib/jsbn/base64 */ \"./lib/lib/jsbn/base64.js\");\n/* harmony import */ var _JSEncryptRSAKey__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./JSEncryptRSAKey */ \"./lib/JSEncryptRSAKey.js\");\n/* provided dependency */ var process = __webpack_require__(/*! process/browser */ \"./node_modules/process/browser.js\");\nvar _a;\n\n\nvar version = typeof process !== 'undefined'\n ? (_a = process.env) === null || _a === void 0 ? void 0 : \"3.3.2\"\n : undefined;\n/**\n *\n * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour\n * possible parameters are:\n * - default_key_size {number} default: 1024 the key size in bit\n * - default_public_exponent {string} default: '010001' the hexadecimal representation of the public exponent\n * - log {boolean} default: false whether log warn/error or not\n * @constructor\n */\nvar JSEncrypt = /** @class */ (function () {\n function JSEncrypt(options) {\n if (options === void 0) { options = {}; }\n options = options || {};\n this.default_key_size = options.default_key_size\n ? parseInt(options.default_key_size, 10)\n : 1024;\n this.default_public_exponent = options.default_public_exponent || \"010001\"; // 65537 default openssl public exponent for rsa key type\n this.log = options.log || false;\n // The private and public key.\n this.key = null;\n }\n /**\n * Method to set the rsa key parameter (one method is enough to set both the public\n * and the private key, since the private key contains the public key paramenters)\n * Log a warning if logs are enabled\n * @param {Object|string} key the pem encoded string or an object (with or without header/footer)\n * @public\n */\n JSEncrypt.prototype.setKey = function (key) {\n if (this.log && this.key) {\n console.warn(\"A key was already set, overriding existing.\");\n }\n this.key = new _JSEncryptRSAKey__WEBPACK_IMPORTED_MODULE_1__.JSEncryptRSAKey(key);\n };\n /**\n * Proxy method for setKey, for api compatibility\n * @see setKey\n * @public\n */\n JSEncrypt.prototype.setPrivateKey = function (privkey) {\n // Create the key.\n this.setKey(privkey);\n };\n /**\n * Proxy method for setKey, for api compatibility\n * @see setKey\n * @public\n */\n JSEncrypt.prototype.setPublicKey = function (pubkey) {\n // Sets the public key.\n this.setKey(pubkey);\n };\n /**\n * Proxy method for RSAKey object's decrypt, decrypt the string using the private\n * components of the rsa key object. Note that if the object was not set will be created\n * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor\n * @param {string} str base64 encoded crypted string to decrypt\n * @return {string} the decrypted string\n * @public\n */\n JSEncrypt.prototype.decrypt = function (str) {\n // Return the decrypted string.\n try {\n return this.getKey().decrypt((0,_lib_jsbn_base64__WEBPACK_IMPORTED_MODULE_0__.b64tohex)(str));\n }\n catch (ex) {\n return false;\n }\n };\n /**\n * Proxy method for RSAKey object's encrypt, encrypt the string using the public\n * components of the rsa key object. Note that if the object was not set will be created\n * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor\n * @param {string} str the string to encrypt\n * @return {string} the encrypted string encoded in base64\n * @public\n */\n JSEncrypt.prototype.encrypt = function (str) {\n // Return the encrypted string.\n try {\n return (0,_lib_jsbn_base64__WEBPACK_IMPORTED_MODULE_0__.hex2b64)(this.getKey().encrypt(str));\n }\n catch (ex) {\n return false;\n }\n };\n /**\n * Proxy method for RSAKey object's sign.\n * @param {string} str the string to sign\n * @param {function} digestMethod hash method\n * @param {string} digestName the name of the hash algorithm\n * @return {string} the signature encoded in base64\n * @public\n */\n JSEncrypt.prototype.sign = function (str, digestMethod, digestName) {\n // return the RSA signature of 'str' in 'hex' format.\n try {\n return (0,_lib_jsbn_base64__WEBPACK_IMPORTED_MODULE_0__.hex2b64)(this.getKey().sign(str, digestMethod, digestName));\n }\n catch (ex) {\n return false;\n }\n };\n Line truncated
/***/
}),
/***/
"./lib/JSEncryptRSAKey.js":
/*!********************************!*\
!*** ./lib/JSEncryptRSAKey.js ***!
\********************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JSEncryptRSAKey\": () => (/* binding */ JSEncryptRSAKey)\n/* harmony export */ });\n/* harmony import */ var _lib_jsbn_base64__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lib/jsbn/base64 */ \"./lib/lib/jsbn/base64.js\");\n/* harmony import */ var _lib_asn1js_hex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lib/asn1js/hex */ \"./lib/lib/asn1js/hex.js\");\n/* harmony import */ var _lib_asn1js_base64__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lib/asn1js/base64 */ \"./lib/lib/asn1js/base64.js\");\n/* harmony import */ var _lib_asn1js_asn1__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lib/asn1js/asn1 */ \"./lib/lib/asn1js/asn1.js\");\n/* harmony import */ var _lib_jsbn_rsa__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lib/jsbn/rsa */ \"./lib/lib/jsbn/rsa.js\");\n/* harmony import */ var _lib_jsbn_jsbn__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./lib/jsbn/jsbn */ \"./lib/lib/jsbn/jsbn.js\");\n/* harmony import */ var _lib_jsrsasign_asn1_1_0__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./lib/jsrsasign/asn1-1.0 */ \"./lib/lib/jsrsasign/asn1-1.0.js\");\nvar __extends = (undefined && undefined.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\n\n\n\n\n\n\n\n/**\n * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object.\n * This object is just a decorator for parsing the key parameter\n * @param {string|Object} key - The key in string format, or an object containing\n * the parameters needed to build a RSAKey object.\n * @constructor\n */\nvar JSEncryptRSAKey = /** @class */ (function (_super) {\n __extends(JSEncryptRSAKey, _super);\n function JSEncryptRSAKey(key) {\n var _this = _super.call(this) || this;\n // Call the super constructor.\n // RSAKey.call(this);\n // If a key key was provided.\n if (key) {\n // If this is a string...\n if (typeof key === \"string\") {\n _this.parseKey(key);\n }\n else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) ||\n JSEncryptRSAKey.hasPublicKeyProperty(key)) {\n // Set the values for the key.\n _this.parsePropertiesFrom(key);\n }\n }\n return _this;\n }\n /**\n * Method to parse a pem encoded string containing both a public or private key.\n * The method will translate the pem encoded string in a der encoded string and\n * will parse private key and public key parameters. This method accepts public key\n * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).\n *\n * @todo Check how many rsa formats use the same format of pkcs #1.\n *\n * The format is defined as:\n * PublicKeyInfo ::= SEQUENCE {\n * algorithm AlgorithmIdentifier,\n * PublicKey BIT STRING\n * }\n * Where AlgorithmIdentifier is:\n * AlgorithmIdentifier ::= SEQUENCE {\n * algorithm OBJECT IDENTIFIER, the OID of the enc algorithm\n * parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)\n * }\n * and PublicKey is a SEQUENCE encapsulated in a BIT STRING\n * RSAPublicKey ::= SEQUENCE {\n * modulus INTEGER, -- n\n * publicExponent INTEGER -- e\n * }\n * it's possible to examine the structure of the keys obtained from openssl using\n * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/\n * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer\n * @private\n */\n JSEncryptRSAKey.prototype.parseKey = function (pem) {\n try {\n var modulus = 0;\n var public_exponent = 0;\n var reHex = /^\\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\\s*)+$/;\n var der = reHex.test(pem) ? _lib_asn1js_hex__WEBPACK_IMPORTED_MODULE_1__.Hex.decode(pem) : _lib_asn1js_base64__WEBPACK_IMPORTED_MODULE_2__.Base64.unarmor(pem);\n var asn1 = _lib_asn1js_asn1__WEBPACK_IMPORTED_MODULE_3__.ASN1.decode(der);\n // Fixes a bug with OpenSSL Line truncated
/***/
}),
/***/
"./lib/index.js":
/*!**********************!*\
!*** ./lib/index.js ***!
\**********************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"JSEncrypt\": () => (/* reexport safe */ _JSEncrypt__WEBPACK_IMPORTED_MODULE_0__.JSEncrypt),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _JSEncrypt__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./JSEncrypt */ \"./lib/JSEncrypt.js\");\n\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_JSEncrypt__WEBPACK_IMPORTED_MODULE_0__.JSEncrypt);\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/index.js?");
/***/
}),
/***/
"./lib/lib/asn1js/asn1.js":
/*!********************************!*\
!*** ./lib/lib/asn1js/asn1.js ***!
\********************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ASN1\": () => (/* binding */ ASN1),\n/* harmony export */ \"ASN1Tag\": () => (/* binding */ ASN1Tag),\n/* harmony export */ \"Stream\": () => (/* binding */ Stream)\n/* harmony export */ });\n/* harmony import */ var _int10__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./int10 */ \"./lib/lib/asn1js/int10.js\");\n// ASN.1 JavaScript decoder\n// Copyright (c) 2008-2014 Lapo Luchini <lapo@lapo.it>\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */\n/*global oids */\n\nvar ellipsis = \"\\u2026\";\nvar reTimeS = /^(\\d\\d)(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])([01]\\d|2[0-3])(?:([0-5]\\d)(?:([0-5]\\d)(?:[.,](\\d{1,3}))?)?)?(Z|[-+](?:[0]\\d|1[0-2])([0-5]\\d)?)?$/;\nvar reTimeL = /^(\\d\\d\\d\\d)(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])([01]\\d|2[0-3])(?:([0-5]\\d)(?:([0-5]\\d)(?:[.,](\\d{1,3}))?)?)?(Z|[-+](?:[0]\\d|1[0-2])([0-5]\\d)?)?$/;\nfunction stringCut(str, len) {\n if (str.length > len) {\n str = str.substring(0, len) + ellipsis;\n }\n return str;\n}\nvar Stream = /** @class */ (function () {\n function Stream(enc, pos) {\n this.hexDigits = \"0123456789ABCDEF\";\n if (enc instanceof Stream) {\n this.enc = enc.enc;\n this.pos = enc.pos;\n }\n else {\n // enc should be an array or a binary string\n this.enc = enc;\n this.pos = pos;\n }\n }\n Stream.prototype.get = function (pos) {\n if (pos === undefined) {\n pos = this.pos++;\n }\n if (pos >= this.enc.length) {\n throw new Error(\"Requesting byte offset \".concat(pos, \" on a stream of length \").concat(this.enc.length));\n }\n return (\"string\" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];\n };\n Stream.prototype.hexByte = function (b) {\n return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);\n };\n Stream.prototype.hexDump = function (start, end, raw) {\n var s = \"\";\n for (var i = start; i < end; ++i) {\n s += this.hexByte(this.get(i));\n if (raw !== true) {\n switch (i & 0xF) {\n case 0x7:\n s += \" \";\n break;\n case 0xF:\n s += \"\\n\";\n break;\n default:\n s += \" \";\n }\n }\n }\n return s;\n };\n Stream.prototype.isASCII = function (start, end) {\n for (var i = start; i < end; ++i) {\n var c = this.get(i);\n if (c < 32 || c > 176) {\n return false;\n }\n }\n return true;\n };\n Stream.prototype.parseStringISO = function (start, end) {\n var s = \"\";\n for (var i = start; i < end; ++i) {\n s += String.fromCharCode(this.get(i));\n }\n return s;\n };\n Stream.prototype.parseStringUTF = function (start, end) {\n var s = \"\";\n for (var i = start; i < end;) {\n var c = this.get(i++);\n if (c < 128) {\n s += String.fromCharCode(c);\n }\n else if ((c > 191) && (c < 224)) {\n s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));\n }\n else {\n s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));\n }\n }\n return s;\n };\n Stream.prototype.parseStringBMP = function (start, end) {\n var str = \"\";\n var hi;\n var lo;\n for (var i = start; i < end;) {\n hi = this.get(i++);\n lo = this.get(i++);\n str += String.fromCharCode((hi << 8) | lo);\n }\n return str;\n };\n Stream.prototype.parseTime = function (start, end, shortYear) {\n var s = this.parseStringISO(start, end);\n var m = (shoLine truncated
/***/
}),
/***/
"./lib/lib/asn1js/base64.js":
/*!**********************************!*\
!*** ./lib/lib/asn1js/base64.js ***!
\**********************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Base64\": () => (/* binding */ Base64)\n/* harmony export */ });\n// Base64 JavaScript decoder\n// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */\nvar decoder;\nvar Base64 = {\n decode: function (a) {\n var i;\n if (decoder === undefined) {\n var b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n var ignore = \"= \\f\\n\\r\\t\\u00A0\\u2028\\u2029\";\n decoder = Object.create(null);\n for (i = 0; i < 64; ++i) {\n decoder[b64.charAt(i)] = i;\n }\n decoder['-'] = 62; //+\n decoder['_'] = 63; //-\n for (i = 0; i < ignore.length; ++i) {\n decoder[ignore.charAt(i)] = -1;\n }\n }\n var out = [];\n var bits = 0;\n var char_count = 0;\n for (i = 0; i < a.length; ++i) {\n var c = a.charAt(i);\n if (c == \"=\") {\n break;\n }\n c = decoder[c];\n if (c == -1) {\n continue;\n }\n if (c === undefined) {\n throw new Error(\"Illegal character at offset \" + i);\n }\n bits |= c;\n if (++char_count >= 4) {\n out[out.length] = (bits >> 16);\n out[out.length] = (bits >> 8) & 0xFF;\n out[out.length] = bits & 0xFF;\n bits = 0;\n char_count = 0;\n }\n else {\n bits <<= 6;\n }\n }\n switch (char_count) {\n case 1:\n throw new Error(\"Base64 encoding incomplete: at least 2 bits missing\");\n case 2:\n out[out.length] = (bits >> 10);\n break;\n case 3:\n out[out.length] = (bits >> 16);\n out[out.length] = (bits >> 8) & 0xFF;\n break;\n }\n return out;\n },\n re: /-----BEGIN [^-]+-----([A-Za-z0-9+\\/=\\s]+)-----END [^-]+-----|begin-base64[^\\n]+\\n([A-Za-z0-9+\\/=\\s]+)====/,\n unarmor: function (a) {\n var m = Base64.re.exec(a);\n if (m) {\n if (m[1]) {\n a = m[1];\n }\n else if (m[2]) {\n a = m[2];\n }\n else {\n throw new Error(\"RegExp out of sync\");\n }\n }\n return Base64.decode(a);\n }\n};\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/asn1js/base64.js?");
/***/
}),
/***/
"./lib/lib/asn1js/hex.js":
/*!*******************************!*\
!*** ./lib/lib/asn1js/hex.js ***!
\*******************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Hex\": () => (/* binding */ Hex)\n/* harmony export */ });\n// Hex JavaScript decoder\n// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */\nvar decoder;\nvar Hex = {\n decode: function (a) {\n var i;\n if (decoder === undefined) {\n var hex = \"0123456789ABCDEF\";\n var ignore = \" \\f\\n\\r\\t\\u00A0\\u2028\\u2029\";\n decoder = {};\n for (i = 0; i < 16; ++i) {\n decoder[hex.charAt(i)] = i;\n }\n hex = hex.toLowerCase();\n for (i = 10; i < 16; ++i) {\n decoder[hex.charAt(i)] = i;\n }\n for (i = 0; i < ignore.length; ++i) {\n decoder[ignore.charAt(i)] = -1;\n }\n }\n var out = [];\n var bits = 0;\n var char_count = 0;\n for (i = 0; i < a.length; ++i) {\n var c = a.charAt(i);\n if (c == \"=\") {\n break;\n }\n c = decoder[c];\n if (c == -1) {\n continue;\n }\n if (c === undefined) {\n throw new Error(\"Illegal character at offset \" + i);\n }\n bits |= c;\n if (++char_count >= 2) {\n out[out.length] = bits;\n bits = 0;\n char_count = 0;\n }\n else {\n bits <<= 4;\n }\n }\n if (char_count) {\n throw new Error(\"Hex encoding incomplete: 4 bits missing\");\n }\n return out;\n }\n};\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/asn1js/hex.js?");
/***/
}),
/***/
"./lib/lib/asn1js/int10.js":
/*!*********************************!*\
!*** ./lib/lib/asn1js/int10.js ***!
\*********************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Int10\": () => (/* binding */ Int10)\n/* harmony export */ });\n// Big integer base-10 printing library\n// Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */\nvar max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256\nvar Int10 = /** @class */ (function () {\n function Int10(value) {\n this.buf = [+value || 0];\n }\n Int10.prototype.mulAdd = function (m, c) {\n // assert(m <= 256)\n var b = this.buf;\n var l = b.length;\n var i;\n var t;\n for (i = 0; i < l; ++i) {\n t = b[i] * m + c;\n if (t < max) {\n c = 0;\n }\n else {\n c = 0 | (t / max);\n t -= c * max;\n }\n b[i] = t;\n }\n if (c > 0) {\n b[i] = c;\n }\n };\n Int10.prototype.sub = function (c) {\n // assert(m <= 256)\n var b = this.buf;\n var l = b.length;\n var i;\n var t;\n for (i = 0; i < l; ++i) {\n t = b[i] - c;\n if (t < 0) {\n t += max;\n c = 1;\n }\n else {\n c = 0;\n }\n b[i] = t;\n }\n while (b[b.length - 1] === 0) {\n b.pop();\n }\n };\n Int10.prototype.toString = function (base) {\n if ((base || 10) != 10) {\n throw new Error(\"only base 10 is supported\");\n }\n var b = this.buf;\n var s = b[b.length - 1].toString();\n for (var i = b.length - 2; i >= 0; --i) {\n s += (max + b[i]).toString().substring(1);\n }\n return s;\n };\n Int10.prototype.valueOf = function () {\n var b = this.buf;\n var v = 0;\n for (var i = b.length - 1; i >= 0; --i) {\n v = v * max + b[i];\n }\n return v;\n };\n Int10.prototype.simplify = function () {\n var b = this.buf;\n return (b.length == 1) ? b[0] : this;\n };\n return Int10;\n}());\n\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/asn1js/int10.js?");
/***/
}),
/***/
"./lib/lib/jsbn/base64.js":
/*!********************************!*\
!*** ./lib/lib/jsbn/base64.js ***!
\********************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"b64toBA\": () => (/* binding */ b64toBA),\n/* harmony export */ \"b64tohex\": () => (/* binding */ b64tohex),\n/* harmony export */ \"hex2b64\": () => (/* binding */ hex2b64)\n/* harmony export */ });\n/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util */ \"./lib/lib/jsbn/util.js\");\n\nvar b64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar b64pad = \"=\";\nfunction hex2b64(h) {\n var i;\n var c;\n var ret = \"\";\n for (i = 0; i + 3 <= h.length; i += 3) {\n c = parseInt(h.substring(i, i + 3), 16);\n ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);\n }\n if (i + 1 == h.length) {\n c = parseInt(h.substring(i, i + 1), 16);\n ret += b64map.charAt(c << 2);\n }\n else if (i + 2 == h.length) {\n c = parseInt(h.substring(i, i + 2), 16);\n ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);\n }\n while ((ret.length & 3) > 0) {\n ret += b64pad;\n }\n return ret;\n}\n// convert a base64 string to hex\nfunction b64tohex(s) {\n var ret = \"\";\n var i;\n var k = 0; // b64 state, 0-3\n var slop = 0;\n for (i = 0; i < s.length; ++i) {\n if (s.charAt(i) == b64pad) {\n break;\n }\n var v = b64map.indexOf(s.charAt(i));\n if (v < 0) {\n continue;\n }\n if (k == 0) {\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(v >> 2);\n slop = v & 3;\n k = 1;\n }\n else if (k == 1) {\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)((slop << 2) | (v >> 4));\n slop = v & 0xf;\n k = 2;\n }\n else if (k == 2) {\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(slop);\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(v >> 2);\n slop = v & 3;\n k = 3;\n }\n else {\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)((slop << 2) | (v >> 4));\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(v & 0xf);\n k = 0;\n }\n }\n if (k == 1) {\n ret += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(slop << 2);\n }\n return ret;\n}\n// convert a base64 string to a byte/number array\nfunction b64toBA(s) {\n // piggyback on b64tohex for now, optimize later\n var h = b64tohex(s);\n var i;\n var a = [];\n for (i = 0; 2 * i < h.length; ++i) {\n a[i] = parseInt(h.substring(2 * i, 2 * i + 2), 16);\n }\n return a;\n}\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/jsbn/base64.js?");
/***/
}),
/***/
"./lib/lib/jsbn/jsbn.js":
/*!******************************!*\
!*** ./lib/lib/jsbn/jsbn.js ***!
\******************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"BigInteger\": () => (/* binding */ BigInteger),\n/* harmony export */ \"intAt\": () => (/* binding */ intAt),\n/* harmony export */ \"nbi\": () => (/* binding */ nbi),\n/* harmony export */ \"nbits\": () => (/* binding */ nbits),\n/* harmony export */ \"nbv\": () => (/* binding */ nbv),\n/* harmony export */ \"parseBigInt\": () => (/* binding */ parseBigInt)\n/* harmony export */ });\n/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util */ \"./lib/lib/jsbn/util.js\");\n// Copyright (c) 2005 Tom Wu\n// All Rights Reserved.\n// See \"LICENSE\" for details.\n// Basic JavaScript BN library - subset useful for RSA encryption.\n\n// Bits per digit\nvar dbits;\n// JavaScript engine analysis\nvar canary = 0xdeadbeefcafe;\nvar j_lm = ((canary & 0xffffff) == 0xefcafe);\n//#region\nvar lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];\nvar lplim = (1 << 26) / lowprimes[lowprimes.length - 1];\n//#endregion\n// (public) Constructor\nvar BigInteger = /** @class */ (function () {\n function BigInteger(a, b, c) {\n if (a != null) {\n if (\"number\" == typeof a) {\n this.fromNumber(a, b, c);\n }\n else if (b == null && \"string\" != typeof a) {\n this.fromString(a, 256);\n }\n else {\n this.fromString(a, b);\n }\n }\n }\n //#region PUBLIC\n // BigInteger.prototype.toString = bnToString;\n // (public) return string representation in given radix\n BigInteger.prototype.toString = function (b) {\n if (this.s < 0) {\n return \"-\" + this.negate().toString(b);\n }\n var k;\n if (b == 16) {\n k = 4;\n }\n else if (b == 8) {\n k = 3;\n }\n else if (b == 2) {\n k = 1;\n }\n else if (b == 32) {\n k = 5;\n }\n else if (b == 4) {\n k = 2;\n }\n else {\n return this.toRadix(b);\n }\n var km = (1 << k) - 1;\n var d;\n var m = false;\n var r = \"\";\n var i = this.t;\n var p = this.DB - (i * this.DB) % k;\n if (i-- > 0) {\n if (p < this.DB && (d = this[i] >> p) > 0) {\n m = true;\n r = (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(d);\n }\n while (i >= 0) {\n if (p < k) {\n d = (this[i] & ((1 << p) - 1)) << (k - p);\n d |= this[--i] >> (p += this.DB - k);\n }\n else {\n d = (this[i] >> (p -= k)) & km;\n if (p <= 0) {\n p += this.DB;\n --i;\n }\n }\n if (d > 0) {\n m = true;\n }\n if (m) {\n r += (0,_util__WEBPACK_IMPORTED_MODULE_0__.int2char)(d);\n }\n }\n }\n return m ? r : \"0\";\n };\n // BigInteger.prototype.negate = bnNegate;\n // (public) -this\n BigInteger.prototype.negate = function () {\n var r = nbi();\n BigInteger.ZERO.subTo(this, r);\n return r;\n };\n // BigInteger.prototype.abs = bnAbs;\n // (public) |this|\n BigInteger.prototype.abs = function () {\n return (this.s < 0) ? this.negate() : this;\n };\n // BigInteger.prototype.compareTo = bnCompareTo;\n // (public) return + if this > a, - if this < a, 0 if equal\n BigInteger.prototype.compareTo = function (a) {\n var r = this.s - a.s;\n if (r != 0) {\n return r;\n }\n var i = this.t;\n r = i - a.t;\n if (r != 0) {\n return (this.s < 0) ? -r : r;\n }\n while (--i >= 0) {\n if ((r = this[i] - a[i]) != 0) {\n return r;\n }\n }\n return 0;\n };\n // BigInteger.protot Line truncated
/***/
}),
/***/
"./lib/lib/jsbn/prng4.js":
/*!*******************************!*\
!*** ./lib/lib/jsbn/prng4.js ***!
\*******************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Arcfour\": () => (/* binding */ Arcfour),\n/* harmony export */ \"prng_newstate\": () => (/* binding */ prng_newstate),\n/* harmony export */ \"rng_psize\": () => (/* binding */ rng_psize)\n/* harmony export */ });\n// prng4.js - uses Arcfour as a PRNG\nvar Arcfour = /** @class */ (function () {\n function Arcfour() {\n this.i = 0;\n this.j = 0;\n this.S = [];\n }\n // Arcfour.prototype.init = ARC4init;\n // Initialize arcfour context from key, an array of ints, each from [0..255]\n Arcfour.prototype.init = function (key) {\n var i;\n var j;\n var t;\n for (i = 0; i < 256; ++i) {\n this.S[i] = i;\n }\n j = 0;\n for (i = 0; i < 256; ++i) {\n j = (j + this.S[i] + key[i % key.length]) & 255;\n t = this.S[i];\n this.S[i] = this.S[j];\n this.S[j] = t;\n }\n this.i = 0;\n this.j = 0;\n };\n // Arcfour.prototype.next = ARC4next;\n Arcfour.prototype.next = function () {\n var t;\n this.i = (this.i + 1) & 255;\n this.j = (this.j + this.S[this.i]) & 255;\n t = this.S[this.i];\n this.S[this.i] = this.S[this.j];\n this.S[this.j] = t;\n return this.S[(t + this.S[this.i]) & 255];\n };\n return Arcfour;\n}());\n\n// Plug in your RNG constructor here\nfunction prng_newstate() {\n return new Arcfour();\n}\n// Pool size must be a multiple of 4 and greater than 32.\n// An array of bytes the size of the pool will be passed to init()\nvar rng_psize = 256;\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/jsbn/prng4.js?");
/***/
}),
/***/
"./lib/lib/jsbn/rng.js":
/*!*****************************!*\
!*** ./lib/lib/jsbn/rng.js ***!
\*****************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"SecureRandom\": () => (/* binding */ SecureRandom)\n/* harmony export */ });\n/* harmony import */ var _prng4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./prng4 */ \"./lib/lib/jsbn/prng4.js\");\n// Random number generator - requires a PRNG backend, e.g. prng4.js\n\nvar rng_state;\nvar rng_pool = null;\nvar rng_pptr;\n// Initialize the pool with junk if needed.\nif (rng_pool == null) {\n rng_pool = [];\n rng_pptr = 0;\n var t = void 0;\n if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {\n // Extract entropy (2048 bits) from RNG if available\n var z = new Uint32Array(256);\n window.crypto.getRandomValues(z);\n for (t = 0; t < z.length; ++t) {\n rng_pool[rng_pptr++] = z[t] & 255;\n }\n }\n // Use mouse events for entropy, if we do not have enough entropy by the time\n // we need it, entropy will be generated by Math.random.\n var count = 0;\n var onMouseMoveListener_1 = function (ev) {\n count = count || 0;\n if (count >= 256 || rng_pptr >= _prng4__WEBPACK_IMPORTED_MODULE_0__.rng_psize) {\n if (window.removeEventListener) {\n window.removeEventListener(\"mousemove\", onMouseMoveListener_1, false);\n }\n else if (window.detachEvent) {\n window.detachEvent(\"onmousemove\", onMouseMoveListener_1);\n }\n return;\n }\n try {\n var mouseCoordinates = ev.x + ev.y;\n rng_pool[rng_pptr++] = mouseCoordinates & 255;\n count += 1;\n }\n catch (e) {\n // Sometimes Firefox will deny permission to access event properties for some reason. Ignore.\n }\n };\n if (typeof window !== 'undefined') {\n if (window.addEventListener) {\n window.addEventListener(\"mousemove\", onMouseMoveListener_1, false);\n }\n else if (window.attachEvent) {\n window.attachEvent(\"onmousemove\", onMouseMoveListener_1);\n }\n }\n}\nfunction rng_get_byte() {\n if (rng_state == null) {\n rng_state = (0,_prng4__WEBPACK_IMPORTED_MODULE_0__.prng_newstate)();\n // At this point, we may not have collected enough entropy. If not, fall back to Math.random\n while (rng_pptr < _prng4__WEBPACK_IMPORTED_MODULE_0__.rng_psize) {\n var random = Math.floor(65536 * Math.random());\n rng_pool[rng_pptr++] = random & 255;\n }\n rng_state.init(rng_pool);\n for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {\n rng_pool[rng_pptr] = 0;\n }\n rng_pptr = 0;\n }\n // TODO: allow reseeding after first request\n return rng_state.next();\n}\nvar SecureRandom = /** @class */ (function () {\n function SecureRandom() {\n }\n SecureRandom.prototype.nextBytes = function (ba) {\n for (var i = 0; i < ba.length; ++i) {\n ba[i] = rng_get_byte();\n }\n };\n return SecureRandom;\n}());\n\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/jsbn/rng.js?");
/***/
}),
/***/
"./lib/lib/jsbn/rsa.js":
/*!*****************************!*\
!*** ./lib/lib/jsbn/rsa.js ***!
\*****************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"RSAKey\": () => (/* binding */ RSAKey)\n/* harmony export */ });\n/* harmony import */ var _jsbn__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./jsbn */ \"./lib/lib/jsbn/jsbn.js\");\n/* harmony import */ var _rng__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rng */ \"./lib/lib/jsbn/rng.js\");\n// Depends on jsbn.js and rng.js\n// Version 1.1: support utf-8 encoding in pkcs1pad2\n// convert a (hex) string to a bignum object\n\n\n// function linebrk(s,n) {\n// var ret = \"\";\n// var i = 0;\n// while(i + n < s.length) {\n// ret += s.substring(i,i+n) + \"\\n\";\n// i += n;\n// }\n// return ret + s.substring(i,s.length);\n// }\n// function byte2Hex(b) {\n// if(b < 0x10)\n// return \"0\" + b.toString(16);\n// else\n// return b.toString(16);\n// }\nfunction pkcs1pad1(s, n) {\n if (n < s.length + 22) {\n console.error(\"Message too long for RSA\");\n return null;\n }\n var len = n - s.length - 6;\n var filler = \"\";\n for (var f = 0; f < len; f += 2) {\n filler += \"ff\";\n }\n var m = \"0001\" + filler + \"00\" + s;\n return (0,_jsbn__WEBPACK_IMPORTED_MODULE_0__.parseBigInt)(m, 16);\n}\n// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint\nfunction pkcs1pad2(s, n) {\n if (n < s.length + 11) { // TODO: fix for utf-8\n console.error(\"Message too long for RSA\");\n return null;\n }\n var ba = [];\n var i = s.length - 1;\n while (i >= 0 && n > 0) {\n var c = s.charCodeAt(i--);\n if (c < 128) { // encode using utf-8\n ba[--n] = c;\n }\n else if ((c > 127) && (c < 2048)) {\n ba[--n] = (c & 63) | 128;\n ba[--n] = (c >> 6) | 192;\n }\n else {\n ba[--n] = (c & 63) | 128;\n ba[--n] = ((c >> 6) & 63) | 128;\n ba[--n] = (c >> 12) | 224;\n }\n }\n ba[--n] = 0;\n var rng = new _rng__WEBPACK_IMPORTED_MODULE_1__.SecureRandom();\n var x = [];\n while (n > 2) { // random non-zero pad\n x[0] = 0;\n while (x[0] == 0) {\n rng.nextBytes(x);\n }\n ba[--n] = x[0];\n }\n ba[--n] = 2;\n ba[--n] = 0;\n return new _jsbn__WEBPACK_IMPORTED_MODULE_0__.BigInteger(ba);\n}\n// \"empty\" RSA key constructor\nvar RSAKey = /** @class */ (function () {\n function RSAKey() {\n this.n = null;\n this.e = 0;\n this.d = null;\n this.p = null;\n this.q = null;\n this.dmp1 = null;\n this.dmq1 = null;\n this.coeff = null;\n }\n //#region PROTECTED\n // protected\n // RSAKey.prototype.doPublic = RSADoPublic;\n // Perform raw public operation on \"x\": return x^e (mod n)\n RSAKey.prototype.doPublic = function (x) {\n return x.modPowInt(this.e, this.n);\n };\n // RSAKey.prototype.doPrivate = RSADoPrivate;\n // Perform raw private operation on \"x\": return x^d (mod n)\n RSAKey.prototype.doPrivate = function (x) {\n if (this.p == null || this.q == null) {\n return x.modPow(this.d, this.n);\n }\n // TODO: re-calculate any missing CRT params\n var xp = x.mod(this.p).modPow(this.dmp1, this.p);\n var xq = x.mod(this.q).modPow(this.dmq1, this.q);\n while (xp.compareTo(xq) < 0) {\n xp = xp.add(this.p);\n }\n return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);\n };\n //#endregion PROTECTED\n //#region PUBLIC\n // RSAKey.prototype.setPublic = RSASetPublic;\n // Set the public key fields N and e from hex strings\n RSAKey.prototype.setPublic = function (N, E) {\n if (N != null && E != null && N.length > 0 && E.length > 0) {\n this.n = (0,_jsbn__WEBPACK_IMPORTED_MODULE_0__.parseBigInt)(N, 16);\n this.e = parseInt(E, 16);\n }\n else {\n console.error(\"Invalid RSA public key\");\n }\n };\n // RSAKey.prototype.encrypt = RSAEncrypt;\n // Return the PKCS#1 RSA encryption of \"text\" as an even-length hex string\n RSAKey.prototype.encrypt = function (text) {\n var maxLength = (this.n.bitLength() + 7) >> 3;\n var m = pkcs1pad2(text, maxLength);\n if (m == null) {\n return null;\n }\n var c = this.doPublic(m);\n if (c == null) {\n return null;\n }\n var h = c.toString(16);\n var length = h.length;\n // fix zero before result\n for (var i = 0; i < maxLength * 2 - length; i++) {\n h = \"0\" + h;\n }\n return h;\n };\n // RSAKey.prototype.setPrivate = RSASetPrivate;\n // Set the private key fields N, e, and d from hex strings\n RSAKey.prototype.setPrivate = function (N, E, Line truncated
/***/
}),
/***/
"./lib/lib/jsbn/util.js":
/*!******************************!*\
!*** ./lib/lib/jsbn/util.js ***!
\******************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"cbit\": () => (/* binding */ cbit),\n/* harmony export */ \"int2char\": () => (/* binding */ int2char),\n/* harmony export */ \"lbit\": () => (/* binding */ lbit),\n/* harmony export */ \"op_and\": () => (/* binding */ op_and),\n/* harmony export */ \"op_andnot\": () => (/* binding */ op_andnot),\n/* harmony export */ \"op_or\": () => (/* binding */ op_or),\n/* harmony export */ \"op_xor\": () => (/* binding */ op_xor)\n/* harmony export */ });\nvar BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";\nfunction int2char(n) {\n return BI_RM.charAt(n);\n}\n//#region BIT_OPERATIONS\n// (public) this & a\nfunction op_and(x, y) {\n return x & y;\n}\n// (public) this | a\nfunction op_or(x, y) {\n return x | y;\n}\n// (public) this ^ a\nfunction op_xor(x, y) {\n return x ^ y;\n}\n// (public) this & ~a\nfunction op_andnot(x, y) {\n return x & ~y;\n}\n// return index of lowest 1-bit in x, x < 2^31\nfunction lbit(x) {\n if (x == 0) {\n return -1;\n }\n var r = 0;\n if ((x & 0xffff) == 0) {\n x >>= 16;\n r += 16;\n }\n if ((x & 0xff) == 0) {\n x >>= 8;\n r += 8;\n }\n if ((x & 0xf) == 0) {\n x >>= 4;\n r += 4;\n }\n if ((x & 3) == 0) {\n x >>= 2;\n r += 2;\n }\n if ((x & 1) == 0) {\n ++r;\n }\n return r;\n}\n// return number of 1 bits in x\nfunction cbit(x) {\n var r = 0;\n while (x != 0) {\n x &= x - 1;\n ++r;\n }\n return r;\n}\n//#endregion BIT_OPERATIONS\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/jsbn/util.js?");
/***/
}),
/***/
"./lib/lib/jsrsasign/asn1-1.0.js":
/*!***************************************!*\
!*** ./lib/lib/jsrsasign/asn1-1.0.js ***!
\***************************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"KJUR\": () => (/* binding */ KJUR)\n/* harmony export */ });\n/* harmony import */ var _jsbn_jsbn__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../jsbn/jsbn */ \"./lib/lib/jsbn/jsbn.js\");\n/* harmony import */ var _yahoo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./yahoo */ \"./lib/lib/jsrsasign/yahoo.js\");\n/* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n/*\n * asn1.js - ASN.1 DER encoder classes\n *\n * Copyright (c) 2013-2017 Kenji Urushima (kenji.urushima@gmail.com)\n *\n * This software is licensed under the terms of the MIT License.\n * https://kjur.github.io/jsrsasign/license\n *\n * The above copyright and license notice shall be\n * included in all copies or substantial portions of the Software.\n */\n\n\n/**\n * @fileOverview\n * @name asn1-1.0.js\n * @author Kenji Urushima kenji.urushima@gmail.com\n * @version asn1 1.0.13 (2017-Jun-02)\n * @since jsrsasign 2.1\n * @license <a href=\"https://kjur.github.io/jsrsasign/license/\">MIT License</a>\n */\n/**\n * kjur's class library name space\n * <p>\n * This name space provides following name spaces:\n * <ul>\n * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>\n * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>\n * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature\n * class and utilities</li>\n * </ul>\n * </p>\n * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.\n * @name KJUR\n * @namespace kjur's class library name space\n */\nvar KJUR = {};\n/**\n * kjur's ASN.1 class library name space\n * <p>\n * This is ITU-T X.690 ASN.1 DER encoder class library and\n * class structure and methods is very similar to\n * org.bouncycastle.asn1 package of\n * well known BouncyCaslte Cryptography Library.\n * <h4>PROVIDING ASN.1 PRIMITIVES</h4>\n * Here are ASN.1 DER primitive classes.\n * <ul>\n * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>\n * <li>0x02 {@link KJUR.asn1.DERInteger}</li>\n * <li>0x03 {@link KJUR.asn1.DERBitString}</li>\n * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>\n * <li>0x05 {@link KJUR.asn1.DERNull}</li>\n * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>\n * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>\n * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>\n * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>\n * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>\n * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>\n * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>\n * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>\n * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>\n * <li>0x30 {@link KJUR.asn1.DERSequence}</li>\n * <li>0x31 {@link KJUR.asn1.DERSet}</li>\n * </ul>\n * <h4>OTHER ASN.1 CLASSES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.ASN1Object}</li>\n * <li>{@link KJUR.asn1.DERAbstractString}</li>\n * <li>{@link KJUR.asn1.DERAbstractTime}</li>\n * <li>{@link KJUR.asn1.DERAbstractStructured}</li>\n * <li>{@link KJUR.asn1.DERTaggedObject}</li>\n * </ul>\n * <h4>SUB NAME SPACES</h4>\n * <ul>\n * <li>{@link KJUR.asn1.cades} - CAdES long term signature format</li>\n * <li>{@link KJUR.asn1.cms} - Cryptographic Message Syntax</li>\n * <li>{@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)</li>\n * <li>{@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format</li>\n * <li>{@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL</li>\n * </ul>\n * </p>\n * NOTE: Please ignore method summary and document of this namespace.\n * This caused by a bug of jsdoc2.\n * @name KJUR.asn1\n * @namespace\n */\nif (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1)\n KJUR.asn1 = {};\n/**\n * ASN1 utilities class\n * @name KJUR.asn1.ASN1Util\n * @class ASN1 utilities class\n * @since asn1 1.0.2\n */\nKJUR.asn1.ASN1Util = new function () {\n this.integerToByteHex = function (i) {\n var h = i.toString(16);\n if ((h.length % 2) == 1)\n h = '0' + h;\n return h;\n };\n this.bigIntToMinTwosComplementsHex = function (bigIntegerValue) {\n var h = bigIntegerValue.toString(16);\n if (h.substr(0, 1) != '-') {\n if (h.length % 2 == 1) {\n h = '0' + h;\n }\n else {\n if (!h.match(/^[0-7]/)) {\n h = '00' + h;\n }\n }\n }\n else {\n var hPos = h.substr(1);\n var xorLen = hPos.length;\n if (xorLen % 2 == 1) {\n xorLen += 1;\n }\n else {\n if (!h.match(/^[0-7]/)) {\n xorLen += 2;\n }\n }\n var hMask = '';\n for (var i = 0; i < xorLen; i++) {\n hMask += 'f';\n Line truncated
/***/
}),
/***/
"./lib/lib/jsrsasign/yahoo.js":
/*!************************************!*\
!*** ./lib/lib/jsrsasign/yahoo.js ***!
\************************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"YAHOO\": () => (/* binding */ YAHOO)\n/* harmony export */ });\n/*!\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nvar YAHOO = {};\nYAHOO.lang = {\n /**\n * Utility to set up the prototype, constructor and superclass properties to\n * support an inheritance strategy that can chain constructors and methods.\n * Static members will not be inherited.\n *\n * @method extend\n * @static\n * @param {Function} subc the object to modify\n * @param {Function} superc the object to inherit\n * @param {Object} overrides additional properties/methods to add to the\n * subclass prototype. These will override the\n * matching items obtained from the superclass\n * if present.\n */\n extend: function (subc, superc, overrides) {\n if (!superc || !subc) {\n throw new Error(\"YAHOO.lang.extend failed, please check that \" +\n \"all dependencies are included.\");\n }\n var F = function () { };\n F.prototype = superc.prototype;\n subc.prototype = new F();\n subc.prototype.constructor = subc;\n subc.superclass = superc.prototype;\n if (superc.prototype.constructor == Object.prototype.constructor) {\n superc.prototype.constructor = superc;\n }\n if (overrides) {\n var i;\n for (i in overrides) {\n subc.prototype[i] = overrides[i];\n }\n /*\n * IE will not enumerate native functions in a derived object even if the\n * function was overridden. This is a workaround for specific functions\n * we care about on the Object prototype.\n * @property _IEEnumFix\n * @param {Function} r the object to receive the augmentation\n * @param {Function} s the object that supplies the properties to augment\n * @static\n * @private\n */\n var _IEEnumFix = function () { }, ADD = [\"toString\", \"valueOf\"];\n try {\n if (/MSIE/.test(navigator.userAgent)) {\n _IEEnumFix = function (r, s) {\n for (i = 0; i < ADD.length; i = i + 1) {\n var fname = ADD[i], f = s[fname];\n if (typeof f === 'function' && f != Object.prototype[fname]) {\n r[fname] = f;\n }\n }\n };\n }\n }\n catch (ex) { }\n ;\n _IEEnumFix(subc.prototype, overrides);\n }\n }\n};\n\n\n//# sourceURL=webpack://JSEncrypt/./lib/lib/jsrsasign/yahoo.js?");
/***/
}),
/***/
"./node_modules/process/browser.js":
/*!*****************************************!*\
!*** ./node_modules/process/browser.js ***!
\*****************************************/
/***/
((module) => {
eval("// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess Line truncated
/***/
})
/******/
});
/************************************************************************/
/******/ // The module cache
/******/
var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/
function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/
var cachedModule = __webpack_module_cache__[moduleId];
/******/
if (cachedModule !== undefined) {
/******/
return cachedModule.exports;
/******/
}
/******/ // Create a new module (and put it into the cache)
/******/
var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/
exports: {}
/******/
};
/******/
/******/ // Execute the module function
/******/
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/
return module.exports;
/******/
}
/******/
/************************************************************************/
/******/
/* webpack/runtime/define property getters */
/******/
(() => {
/******/ // define getter functions for harmony exports
/******/
__webpack_require__.d = (exports, definition) => {
/******/
for (var key in definition) {
/******/
if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key]
});
/******/
}
/******/
}
/******/
};
/******/
})();
/******/
/******/
/* webpack/runtime/hasOwnProperty shorthand */
/******/
(() => {
/******/
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/
})();
/******/
/******/
/* webpack/runtime/make namespace object */
/******/
(() => {
/******/ // define __esModule on exports
/******/
__webpack_require__.r = (exports) => {
/******/
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
/******/
}
/******/
Object.defineProperty(exports, '__esModule', {
value: true
});
/******/
};
/******/
})();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/
var __webpack_exports__ = __webpack_require__("./lib/index.js");
/******/
__webpack_exports__ = __webpack_exports__["default"];
/******/
/******/
return __webpack_exports__;
/******/
})();
});
-1809
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-1439
View File
File diff suppressed because it is too large. Load diff
-475
View File
@@ -1,475 +0,0 @@
import 'assets://lib/crypto-js.js';
const UA = 'Mozilla/5.0 (Linux; Android 9; V2196A Build/PQ3A.190705.08211809; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Mobile Safari/537.36;webank/h5face;webank/1.0;netType:NETWORK_WIFI;appVersion:416;packageName:com.jp3.xg3';
const aggConfig = {
keys: 'd3dGiJc651gSQ8w1',
charMap: {
'+': 'P', '/': 'X', '0': 'M', '1': 'U', '2': 'l', '3': 'E', '4': 'r', '5': 'Y', '6': 'W', '7': 'b', '8': 'd', '9': 'J',
'A': '9', 'B': 's', 'C': 'a', 'D': 'I', 'E': '0', 'F': 'o', 'G': 'y', 'H': '_', 'I': 'H', 'J': 'G', 'K': 'i', 'L': 't',
'M': 'g', 'N': 'N', 'O': 'A', 'P': '8', 'Q': 'F', 'R': 'k', 'S': '3', 'T': 'h', 'U': 'f', 'V': 'R', 'W': 'q', 'X': 'C',
'Y': '4', 'Z': 'p', 'a': 'm', 'b': 'B', 'c': 'O', 'd': 'u', 'e': 'c', 'f': '6', 'g': 'K', 'h': 'x', 'i': '5', 'j': 'T',
'k': '-', 'l': '2', 'm': 'z', 'n': 'S', 'o': 'Z', 'p': '1', 'q': 'V', 'r': 'v', 's': 'j', 't': 'Q', 'u': '7', 'v': 'D',
'w': 'w', 'x': 'n', 'y': 'L', 'z': 'e'
},
headers: {
default: { 'User-Agent': 'okhttp/3.12.11', 'content-type': 'application/json; charset=utf-8' }
},
platform: {
百度: { host: 'https://api.jkyai.top', url1: '/API/bddjss.php?name=fyclass&page=fypage', url2: '/API/bddjss.php?id=fyid', search: '/API/bddjss.php?name=**&page=fypage' },
锦鲤: { host: 'https://api.jinlidj.com', search: '/api/search', url2: '/api/detail' },
番茄: { host: 'https://reading.snssdk.com', url1: '/reading/bookapi/bookmall/cell/change/v', url2: 'https://fqgo.52dns.cc/catalog', search: 'https://fqgo.52dns.cc/search' },
星芽: { host: 'https://app.whjzjx.cn', url1: '/cloud/v2/theater/home_page?theater_class_id', url2: '/v2/theater_parent/detail', search: '/v3/search', loginUrl: 'https://u.shytkjgs.com/user/v1/account/login' },
西饭: { host: 'https://xifan-api-cn.youlishipin.com', url1: '/xifan/drama/portalPage', url2: '/xifan/drama/getDuanjuInfo', search: '/xifan/search/getSearchList' },
软鸭: { host: 'https://api.xingzhige.com', url1: '/API/playlet', search: '/API/playlet' },
七猫: { host: 'https://api-store.qmplaylet.com', url1: '/api/v1/playlet/index', url2: 'https://api-read.qmplaylet.com/player/api/v1/playlet/info', search: '/api/v1/playlet/search' },
围观: { host: 'https://api.drama.9ddm.com', url1: '/drama/home/shortVideoTags', url2: '/drama/home/shortVideoDetail', search: '/drama/home/search' },
甜圈: { host: 'https://mov.cenguigui.cn', url1: '/duanju/api.php?classname', url2: '/duanju/api.php?book_id', search: '/duanju/api.php?name' }
},
platformList: [
{ name: '甜圈短剧', id: '甜圈' }, { name: '七猫短剧', id: '七猫' }, { name: '锦鲤短剧', id: '锦鲤' },
{ name: '番茄短剧', id: '番茄' }, { name: '星芽短剧', id: '星芽' }, { name: '西饭短剧', id: '西饭' },
{ name: '软鸭短剧', id: '软鸭' }, { name: '百度短剧', id: '百度' }, { name: '围观短剧', id: '围观' }
],
search: { limit: 30, timeout: 6000 }
};
const ruleFilterDef = {
百度: { area: '逆袭' },
锦鲤: { area: '' },
番茄: { area: 'videoseries_hot' },
星芽: { area: '1' },
西饭: { area: '' },
软鸭: { area: '战神' },
七猫: { area: '0' },
围观: { area: '' },
甜圈: { area: '推荐榜' }
};
const filterOptionsB64 = "eyLnlJzlnIgiOlt7ImtleSI6ImFyZWEiLCJuYW1lIjoi5Ymn5oOFIiwidmFsdWUiOlt7Im4iOiLlhajpg6giLCJ2IjoiIn0seyJuIjoi5o6o6I2Q5qacIiwidiI6IuaOqOiNkOamnCJ9LHsibiI6IueDreaSreamnCIsInYiOiLng63mkq3mppwifSx7Im4iOiLmlrDkuabmppwiLCJ2Ijoi5paw5Lmm5qacIn0seyJuIjoi5a6M57uT5qacIiwidiI6IuWujOe7k+amnCJ9LHsibiI6Iui/nui9veamnCIsInYiOiLov57ovb3mppwifSx7Im4iOiLlhY3otLnmppwiLCJ2Ijoi5YWN6LS55qacIn0seyJuIjoi5paw5YmnIiwidiI6IuaWsOWJpyJ9LHsibiI6IumAhuiirSIsInYiOiLpgIbooq0ifSx7Im4iOiLpnLjmgLsiLCJ2Ijoi6Zy45oC7In0seyJuIjoi546w5Luj6KiA5oOFIiwidiI6IueOsOS7o+iogOaDhSJ9LHsibiI6IuaJk+iEuOiZkOa4oyIsInYiOiLmiZPohLjomZDmuKMifSx7Im4iOiLosarpl6jmganmgKgiLCJ2Ijoi6LGq6Zeo5oGp5oCoIn0seyJuIjoi56We6LGqIiwidiI6IuelnuixqiJ9LHsibiI6IumprOeUsiIsInYiOiLpqaznlLIifSx7Im4iOiLpg73luILml6XluLgiLCJ2Ijoi6YO95biC5pel5bi4In0seyJuIjoi5oiY56We5b2S5p2lIiwidiI6IuaImOelnuW9kuadpSJ9LHsibiI6IuWwj+S6uueJqSIsInYiOiLlsI/kurrniakifSx7Im4iOiLlpbPmgKfmiJDplb8iLCJ2Ijoi5aWz5oCn5oiQ6ZW/In0seyJuIjoi5aSn5aWz5Li7IiwidiI6IuWkp+Wls+S4uyJ9LHsibiI6Iuepv+i2iiIsInYiOiLnqb/otooifSx7Im4iOiLpg73luILkv67ku5kiLCJ2Ijoi6YO95biC5L+u5LuZIn0seyJuIjoi5by66ICF5Zue5b2SIiwidiI6IuW8uuiAheWbnuW9kiJ9LHsibiI6IuS6suaDhSIsInYiOiLkurLmg4UifSx7Im4iOiLlj6Too4UiLCJ2Ijoi5Y+k6KOFIn0seyJuIjoi6YeN55SfIiwidiI6IumHjeeUnyJ9LHsibiI6IumXquWpmiIsInYiOiLpl6rlqZoifSx7Im4iOiLotZjlqb/pgIbooq0iLCJ2Ijoi6LWY5am/6YCG6KKtIn0seyJuIjoi6JmQ5oGLIiwidiI6IuiZkOaBiyJ9LHsibiI6Iui/veWmuyIsInYiOiLov73lprsifSx7Im4iOiLlpKnkuIvml6DmlYwiLCJ2Ijoi5aSp5LiL5peg5pWMIn0seyJuIjoi5a625bqt5Lym55CGIiwidiI6IuWutuW6reS8pueQhiJ9LHsibiI6IuiQjOWunSIsInYiOiLokIzlrp0ifSx7Im4iOiLlj6Tpo47mnYPosIsiLCJ2Ijoi5Y+k6aOO5p2D6LCLIn0seyJuIjoi6IGM5Zy6IiwidiI6IuiBjOWcuiJ9LHsibiI6IuWlh+W5u+iEkea0niIsInYiOiLlpYflubvohJHmtJ4ifSx7Im4iOiLlvILog70iLCJ2Ijoi5byC6IO9In0seyJuIjoi5peg5pWM56We5Yy7IiwidiI6IuaXoOaVjOelnuWMuyJ9LHsibiI6IuWPpOmjjuiogOaDhSIsInYiOiLlj6Tpo47oqIDmg4UifSx7Im4iOiLkvKDmib/op4nphpIiLCJ2Ijoi5Lyg5om/6KeJ6YaSIn0seyJuIjoi546w6KiA55Sc5a6gIiwidiI6IueOsOiogOeUnOWuoCJ9LHsibiI6IuWlh+W5u+eIseaDhSIsInYiOiLlpYflubvniLHmg4UifSx7Im4iOiLkuaHmnZEiLCJ2Ijoi5Lmh5p2RIn0seyJuIjoi5Y6G5Y+y5Y+k5LujIiwidiI6IuWOhuWPsuWPpOS7oyJ9LHsibiI6IueOi+WmgyIsInYiOiLnjovlpoMifSx7Im4iOiLpq5jmiYvkuIvlsbEiLCJ2Ijoi6auY5omL5LiL5bGxIn0seyJuIjoi5aix5LmQ5ZyIIiwidiI6IuWoseS5kOWciCJ9XX1dLCLplKbpsqQiOlt7ImtleSI6ImFyZWEiLCJuYW1lIjoi5YiG57G7IiwidmFsdWUiOlt7Im4iOiLlhajpg6giLCJ2IjoiIn0seyJuIjoi5oOF5oSf5YWz57O7IiwidiI6IjEifSx7Im4iOiLmiJDplb/pgIbooq0iLCJ2IjoiMiJ9LHsibiI6IuWlh+W5u+W8guiDvSIsInYiOiIzIn0seyJuIjoi5oiY5paX54Ot6KGAIiwidiI6IjQifSx7Im4iOiLkvKbnkIbnjrDlrp4iLCJ2IjoiNSJ9LHsibiI6IuaXtuepuuepv+i2iiIsInYiOiI2In0seyJuIjoi5p2D6LCL6Lqr5Lu9IiwidiI6IjcifV19XSwi55Wq6IyEIjpbeyJrZXkiOiJhcmVhIiwibmFtZSI6IuWIhuexuyIsInZhbHVlIjpbeyJuIjoi54Ot5YmnIiwidiI6InZpZGVvc2VyaWVzX2hvdCJ9LHsibiI6IuaWsOWJpyIsInYiOiJmaXJzdG9ubGluZXRpbWVfbmV3In0seyJuIjoi6YCG6KKtIiwidiI6ImNhdGVfNzM5In0seyJuIjoi5oC76KOBIiwidiI6ImNhdGVfMjkifSx7Im4iOiLnjrDoqIAiLCJ2IjoiY2F0ZV8zIn0seyJuIjoi5omT6IS4IiwidiI6ImNhdGVfMTA1MSJ9LHsibiI6IumprOeUsiIsInYiOiJjYXRlXzI2NiJ9LHsibiI6IuixqumXqCIsInYiOiJjYXRlXzEwNTMifSx7Im4iOiLpg73luIIiLCJ2IjoiY2F0ZV8yNjEifSx7Im4iOiLnpZ7osaoiLCJ2IjoiY2F0ZV8yMCJ9XX1dLCLmmJ/oir0iOlt7ImtleSI6ImFyZWEiLCJuYW1lIjoi5YiG57G7IiwidmFsdWUiOlt7Im4iOiLliaflnLoiLCJ2IjoiMSJ9LHsibiI6IueDreaSreWJpyIsInYiOiIyIn0seyJuIjoi5Lya5ZGY5LiT5LqrIiwidiI6IjgifSx7Im4iOiLmmJ/pgInlpb3liaciLCJ2IjoiNyJ9LHsibiI6IuaWsOWJpyIsInYiOiIzIn0seyJuIjoi6Ziz5YWJ5Ymn5Zy6IiwidiI6IjUifV19XSwi6KW/6aWtIjpbeyJrZXkiOiJhcmVhIiwibmFtZSI6IuWIhuexuyIsInZhbHVlIjpbeyJuIjoi5YWo6YOoIiwidiI6IiJ9LHsibiI6IumDveW4giIsInYiOiI2OEDpg73luIIifSx7Im4iOiLpnZLmmKUiLCJ2IjoiNjhA6Z2S5pilIn0seyJuIjoi546w5Luj6KiA5oOFIiwidiI6IjgxQOeOsOS7o+iogOaDhSJ9LHsibiI6IuixqumXqCIsInYiOiI4MUDosarpl6gifSx7Im4iOiLlpKflpbPkuLsiLCJ2IjoiODBA5aSn5aWz5Li7In0seyJuIjoi6YCG6KKtIiwidiI6Ijc5QOmAhuiirSJ9LHsibiI6IuaJk+iEuOiZkOa4oyIsInYiOiI3OUDmiZPohLjomZDmuKMifSx7Im4iOiLnqb/otooiLCJ2IjoiODFA56m/6LaKIn1dfV0sIui9r+m4rSI6W3sia2V5IjoiYXJlYSIsIm5hbWUiOiLliIbnsbsiLCJ2YWx1ZSI6W3sibiI6IuWFqOmDqCIsInYiOiIifSx7Im4iOiLmiJjnpZ4iLCJ2Ijoi5oiY56WeIn0seyJuIjoi6YCG6KKtIiwidiI6IumAhuiirSJ9LHsibiI6IumcuOaAuyIsInYiOiLpnLjmgLsifSx7Im4iOiLnpZ7osaoiLCJ2Ijoi56We6LGqIn0seyJuIjoi6YO95biCIiwidiI6IumDveW4giJ9LHsibiI6IueOhOW5uyIsInYiOiLnjoTlubsifSx7Im4iOiLoqIDmg4UiLCJ2Ijoi6KiA5oOFIn1dfV0sIuS4g+eMqyI6W3sia2V5IjoiYXJlYSIsIm5hbWUiOiLliIbnsbsiLCJ2YWx1ZSI6W3sibiI6IuWFqOmDqCIsInYiOiIifSx7Im4iOiLmjqjojZAiLCJ2IjoiMCJ9LHsibiI6IuaWsOWJpyIsInYiOiItMSJ9LHsibiI6IumDveW4guaDheaEnyIsInYiOiIxMjczIn0seyJuIjoi5Y+k6KOFIiwidiI6IjEyNzIifSx7Im4iOiLpg73luIIiLCJ2IjoiNTcxIn0seyJuIjoi546E5bm75LuZ5L6gIiwidiI6IjEyODYifSx7Im4iOiLlpYflubsiLCJ2IjoiNTcwIn0seyJuIjoi5Lmh5p2RIiwidiI6IjU5MCJ9LHsibiI6IuawkeWbvSIsInYiOiI1NzMifSx7Im4iOiLlubTku6MiLCJ2IjoiNTcyIn0seyJuIjoi6Z2S5pil5qCh5ZutIiwidiI6IjEyODgifSx7Im4iOiLmrabkvqAiLCJ2IjoiMzcxIn0seyJuIjoi56eR5bm7IiwidiI6IjU5NCJ9LHsibiI6Iuacq+S4liIsInYiOiI1NTYifSx7Im4iOiLkuozmrKHlhYMiLCJ2IjoiMTI4OSJ9LHsibiI6IumAhuiirSIsInYiOiI0MDAifSx7Im4iOiLnqb/otooiLCJ2IjoiMzczIn0seyJuIjoi5aSN5LuHIiwidiI6Ijc5NSJ9LHsibiI6Iuezu+e7nyIsInYiOiI3ODcifSx7Im4iOiLmnYPosIsiLCJ2IjoiNzkwIn0seLine truncated
let xingya_headers = {};
function base64Encode(text) {
return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text));
}
function base64Decode(text) {
return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text));
}
async function request(url, options = {}) {
const { method = 'GET', headers = {}, body, timeout = 5000 } = options;
const isPost = method.toUpperCase() === 'POST';
let requestBody = body && typeof body === 'object' ? JSON.stringify(body) : body;
if (typeof req !== 'undefined') {
return (await req(url, {
method,
headers: { ...aggConfig.headers.default, ...headers },
body: isPost ? requestBody : null,
timeout
})).content;
}
}
async function md5(str) {
return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex).toLowerCase();
}
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
function getFilterOptions() {
try {
return JSON.parse(base64Decode(filterOptionsB64));
} catch (e) {
console.error('filterOptions 解码失败', e);
return {};
}
}
async function getQmParamsAndSign() {
const sessionId = Date.now().toString();
const data = {
"static_score": "0.8",
"uuid": "00000000-7fc7-08dc-0000-000000000000",
"device-id": "20250220125449b9b8cac84c2dd3d035c9052a2572f7dd0122edde3cc42a70",
"sourceuid": "aa7de295aad621a6",
"refresh-type": "0",
"model": "22021211RC",
"client-id": "aa7de295aad621a6",
"brand": "Redmi",
"sys-ver": "12",
"phone-level": "H",
"wlb-uid": "aa7de295aad621a6",
"session-id": sessionId
};
const jsonStr = JSON.stringify(data);
const base64Str = base64Encode(unescape(encodeURIComponent(jsonStr)));
let qmParams = '';
for (const c of base64Str) {
qmParams += aggConfig.charMap[c] || c;
}
const paramsStr = `AUTHORIZATION=app-version=10001application-id=com.duoduo.readchannel=unknownis-white=net-env=5platform=androidqm-params=${qmParams}reg=${aggConfig.keys}`;
const sign = await md5(paramsStr);
return { qmParams, sign };
}
async function getHeaderX() {
const { qmParams, sign } = await getQmParamsAndSign();
return {
'net-env': '5',
'reg': '',
'channel': 'unknown',
'is-white': '',
'platform': 'android',
'application-id': 'com.duoduo.read',
'authorization': '',
'app-version': '10001',
'user-agent': 'webviewversion/0',
'qm-params': qmParams,
'sign': sign
};
}
async function init(cfg) {
try {
const res = JSON.parse(await request(aggConfig.platform.星芽.loginUrl, {
method: 'POST',
headers: { 'User-Agent': 'okhttp/4.10.0', platform: '1', 'Content-Type': 'application/json' },
body: JSON.stringify({ device: '24250683a3bdb3f118dff25ba4b1cba1a' })
}));
const token = res?.data?.token || res?.token;
xingya_headers = token ? { ...aggConfig.headers.default, authorization: token } : aggConfig.headers.default;
} catch (e) {
xingya_headers = aggConfig.headers.default;
}
return true;
}
async function getXingyaHeaders() {
return xingya_headers.authorization ? xingya_headers : aggConfig.headers.default;
}
async function home(filter) {
const classes = aggConfig.platformList.map(p => ({ type_name: p.name, type_id: p.id }));
const filters = {};
const filterOptions = getFilterOptions();
aggConfig.platformList.forEach(item => {
const platformId = item.id;
if (filterOptions[platformId]) {
filters[platformId] = filterOptions[platformId];
}
});
return JSON.stringify({ class: classes, filters });
}
async function homeVod() { return await recommend(); }
async function recommend() {
const randomPlat = aggConfig.platformList[Math.floor(Math.random() * aggConfig.platformList.length)];
const platId = randomPlat.id;
const area = ruleFilterDef[platId]?.area || '';
const videos = await category(platId, 1, false, { area });
const list = JSON.parse(videos).list.slice(0, 10).map(v => ({ ...v, vod_content: `${randomPlat.name} | ${v.vod_remarks}` }));
return JSON.stringify({ list });
}
async function category(tid, pg, filter, extend) {
const plat = aggConfig.platform[tid];
const area = (extend?.area !== undefined ? extend.area : ruleFilterDef[tid]?.area) || '';
const page = parseInt(pg) || 1;
const videos = [];
if (!plat) return JSON.stringify({ list: videos, page, pagecount: 1, limit: 0, total: 0 });
try {
if (tid === '七猫') {
const sign = await md5(`operation=1playlet_privacy=1tag_id=${area}${aggConfig.keys}`);
const url = `${plat.host}${plat.url1}?tag_id=${area}&playlet_privacy=1&operation=1&sign=${sign}`;
const res = JSON.parse(await request(url, { headers: { ...await getHeaderX(), ...aggConfig.headers.default } }));
(res?.data?.list || []).forEach(i => videos.push({
vod_id: `七猫@${encodeURIComponent(i.playlet_id)}`,
vod_name: i.title,
vod_pic: i.image_link,
vod_remarks: `${i.total_episode_num}集`
}));
} else if (tid === '百度') {
const url = `${plat.host}${plat.url1.replace('fyclass', area).replace('fypage', page)}`;
const res = JSON.parse(await request(url));
if (res?.data) videos.push(...res.data.map(i => ({
vod_id: `百度@${i.id}`, vod_name: i.title, vod_pic: i.cover, vod_remarks: `更新至${i.totalChapterNum}集`
})));
} else if (tid === '锦鲤') {
const res = JSON.parse(await request(plat.host + plat.search, { method: 'POST', body: JSON.stringify({ page, limit: 24, type_id: area, keyword: '' }) }));
if (res?.data?.list) videos.push(...res.data.list.map(i => ({
vod_id: `锦鲤@${i.vod_id}`, vod_name: i.vod_name, vod_pic: i.vod_pic, vod_remarks: `${i.vod_total}集`
})));
} else if (tid === '番茄') {
const sessionId = new Date().toISOString().slice(0, 16).replace(/-|T:/g, '');
let url = `${plat.host}${plat.url1}?change_type=0&selected_items=${area}&tab_type=8&cell_id=6952850996422770718&version_tag=video_feed_refactor&device_id=1423244030195267&aid=1967&app_name=novelapp&ssmix=a&session_id=${sessionId}`;
if (page > 1) url += `&offset=${(page - 1) * 12}`;
const res = JSON.parse(await request(url));
const items = res?.data?.cell_view?.cell_data || (Array.isArray(res?.data) ? res.data : []);
items.forEach(i => {
const v = i.video_data?.[0] || i;
videos.push({ vod_id: `番茄@${v.series_id || v.book_id || ''}`, vod_name: v.title, vod_pic: v.cover || v.horiz_cover, vod_remarks: v.sub_title || '' });
});
} else if (tid === '星芽') {
const headers = await getXingyaHeaders();
const url = `${plat.host}${plat.url1}=${area}&type=1&class2_ids=0&page_num=${page}&page_size=24`;
const res = JSON.parse(await request(url, { headers }));
if (res?.data?.list) videos.push(...res.data.list.map(i => ({
vod_id: `星芽@${plat.host}${plat.url2}?theater_parent_id=${i.theater.id}`,
vod_name: i.theater.title, vod_pic: i.theater.cover_url, vod_remarks: `${i.theater.total}集`
})));
} else if (tid === '西饭') {
const [typeId, typeName] = area.split('@');
const ts = Math.floor(Date.now() / 1000);
const url = `${plat.host}${plat.url1}?reqType=aggregationPage&offset=${(page - 1) * 30}&categoryId=${typeId}&quickEngineVersion=-1&scene=&categoryNames=${encodeURIComponent(typeName || '')}&categoryVersion=1&density=1.5&pageID=page_theater&version=2001001&androidVersionCode=28&requestId=${ts}aa498144140ef297&appId=drama&teenMode=false&userBaseMode=false&session=eyJpbmZvIjp7InVpZCI6IiIsInJ0IjoiMTc0MDY1ODI5NCIsInVuIjoiT1BHXzFlZGQ5OTZhNjQ3ZTQ1MjU4Nzc1MTE2YzFkNzViN2QwIiwiZnQiOiIxNzQwNjU4Mjk0In19&feedssession=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dHlwIjowLCJidWlkIjoxNjMzOTY4MTI2MTQ4NjQxNTM2LCJhdWQiOiJkcmFtYSIsInZlciI6MiwicmF0IjoxNzQwNjU4Mjk0LCJ1bm0iOiJPUEdfMWVkZDk5NmE2NDdlNDUyNTg3NzUxMTZjMWQ3NWI3ZDAiLCJpZCI6IjNiMzViZmYzYWE0OTgxNDQxNDBlZjI5N2JkMDY5NGNhIiwiZXhwIjoxNzQxMjYzMDk0LCJkYyI6Imd6cXkifQ.JS3QY6ER0P2cQSxAE_OGKSMIWNAMsYUZ3mJTnEpf-Rc`;
const res = JSON.parse(await request(url, { headers: aggConfig.headers.default }));
const elements = res?.result?.elements || [];
elements.forEach(s => (s.contents || []).forEach(v => {
const d = v.duanjuVo;
if (d) {
videos.push({ vod_id: `西饭@${d.duanjuId}#${d.source}`, vod_name: d.title, vod_pic: d.coverImageUrl, vod_remarks: `${d.total}集` });
}
}));
} else if (tid === '软鸭') {
const url = `${plat.host}${plat.url1}/?keyword=${encodeURIComponent(area)}&page=${page}`;
const res = JSON.parse(await request(url));
if (res?.data) videos.push(...res.data.map(i => {
const purl = `${i.title}@${i.cover}@${i.author}@${i.type}@${i.desc}@${i.book_id}`;
return { vod_id: `软鸭@${encodeURIComponent(purl)}`, vod_name: i.title, vod_pic: i.cover, vod_remarks: i.type };
}));
} else if (tid === '围观') {
const res = JSON.parse(await request(`${plat.host}${plat.search}`, {
method: 'POST', body: JSON.stringify({ audience: "全部受众", page, pageSize: 30, searchWord: "", subject: "全部主题" })
}));
if (res?.data) videos.push(...res.data.map(i => ({
vod_id: `围观@${i.oneId}`, vod_name: i.title, vod_pic: i.vertPoster, vod_remarks: `集数:${i.episodeCount} 播放:${i.viewCount}`
})));
} else if (tid === '甜圈') {
const url = `${plat.host}${plat.url1}=${encodeURIComponent(area)}&offset=${page}`;
const res = JSON.parse(await request(url));
if (res?.data) {
videos.push(...res.data.map(i => ({
vod_id: `甜圈@${i.book_id}`,
vod_name: i.title,
vod_pic: i.cover,
vod_remarks: `${i.sub_title || ''}`
})));
}
}
} catch (e) { }
return JSON.stringify({ list: videos, page, pagecount: page + 1, limit: videos.length, total: videos.length * (page + 1) });
}
async function detail(id) {
const [platId, ...rest] = id.split('@');
const did = rest.join('@');
const plat = aggConfig.platform[platId];
if (!plat) return JSON.stringify({ list: [{ vod_id: id, vod_name: '平台不支持', vod_play_url: '' }] });
let vod = { vod_id: id, vod_name: '未知', vod_pic: '', vod_remarks: '', vod_content: '', vod_play_from: '', vod_play_url: '' };
try {
if (platId === '七猫') {
const didDecoded = decodeURIComponent(did);
const sign = await md5(`playlet_id=${didDecoded}${aggConfig.keys}`);
const url = `${plat.url2}?playlet_id=${didDecoded}&sign=${sign}`;
const res = JSON.parse(await request(url, { headers: { ...await getHeaderX(), ...aggConfig.headers.default } }));
if (res?.data) {
const d = res.data;
vod = {
...vod,
vod_name: d.title,
vod_pic: d.image_link,
vod_remarks: `${d.total_episode_num}集`,
vod_content: d.intro,
vod_play_from: '七猫短剧',
vod_play_url: (d.play_list || []).map(i => `${i.sort}$${i.video_url}`).join('#')
};
}
} else if (platId === '百度') {
const res = JSON.parse(await request(`${plat.host}${plat.url2.replace('fyid', did)}`));
if (res) vod = { ...vod, vod_name: res.title, vod_pic: res.data?.[0]?.cover, vod_remarks: `更新至:${res.total || 0}集`, vod_play_from: '百度短剧', vod_play_url: (res.data || []).map(i => `${i.title}$${i.video_id}`).join('#') };
} else if (platId === '锦鲤') {
const res = JSON.parse(await request(`${plat.host}${plat.url2}/${did}`));
if (res?.data) {
const list = res.data;
const urls = list.player ? Object.keys(list.player).map(k => `${k}$${list.player[k]}`) : [];
vod = { ...vod, vod_name: list.vod_name, vod_pic: list.vod_pic, vod_remarks: list.vod_remarks, vod_play_from: '锦鲤短剧', vod_play_url: urls.join('#') };
}
} else if (platId === '番茄') {
const res = JSON.parse(await request(`${plat.url2}?book_id=${did}`));
if (res?.data) {
const b = res.data.book_info;
const u = (res.data.item_data_list || []).map(i => `${i.title}$${i.item_id}`).join('#');
vod = { ...vod, vod_name: b.book_name, vod_pic: b.thumb_url, vod_remarks: `更新至${res.data.item_data_list?.length}集`, vod_play_from: '番茄短剧', vod_play_url: u };
}
} else if (platId === '星芽') {
const headers = await getXingyaHeaders();
const res = JSON.parse(await request(did, { headers }));
if (res?.data) {
const d = res.data;
const u = (d.theaters || []).map(i => `${i.num}$${i.son_video_url}`).join('#');
vod = { ...vod, vod_name: d.title, vod_pic: d.cover_url, vod_remarks: d.desc_tags + '', vod_play_from: '星芽短剧', vod_play_url: u };
}
} else if (platId === '西饭') {
const [duanjuId, source] = did.split('#');
const url = `${plat.host}${plat.url2}?duanjuId=${duanjuId}&source=${source}`;
const res = JSON.parse(await request(url));
if (res?.result) {
const d = res.result;
const u = (d.episodeList || []).map(e => `${e.index}$${e.playUrl}`).join('#');
vod = { ...vod, vod_name: d.title, vod_pic: d.coverImageUrl, vod_remarks: d.updateStatus === 'over' ? `${d.total}集 已完结` : `更新${d.total}集`, vod_play_from: '西饭短剧', vod_play_url: u };
}
} else if (platId === '甜圈') {
const url = `${plat.host}${plat.url2}=${did}`;
const res = JSON.parse(await request(url));
if (res) {
const u = (res.data || []).map(item => `${item.title}$${item.video_id}`).join('#');
vod = { ...vod, vod_name: res.book_name, vod_pic: res.book_pic, vod_remarks: `${res.duration || ''}`, vod_content: res.desc || '', vod_play_from: '甜圈短剧', vod_play_url: u };
}
} else if (platId === '软鸭') {
const didDecoded = decodeURIComponent(did);
const [title, img, author, type, desc, book_id] = didDecoded.split('@');
const detailUrl = `${plat.host}${plat.url1}/?book_id=${book_id || did.split('@')[5]}`;
const res = JSON.parse(await request(detailUrl, { headers: aggConfig.headers.default }));
const u = (res.data?.video_list || []).map(e => `${e.title}$${e.video_id}`).join('#');
vod = { ...vod, vod_name: title, vod_pic: img, vod_remarks: type, vod_content: desc, vod_play_from: '软鸭短剧', vod_play_url: u };
} else if (platId === '围观') {
const res = JSON.parse(await request(`${plat.host}${plat.url2}?oneId=${did}&page=1&pageSize=1000`));
if (res?.data?.length) {
const d = res.data;
vod = { ...vod, vod_name: d[0].title, vod_pic: d[0].vertPoster, vod_remarks: `共${d.length}集`, vod_play_from: '围观短剧', vod_play_url: d.map(e => `${e.title}第${e.playOrder}集$${e.playSetting}`).join('#') };
}
}
} catch (e) { vod.vod_name = '加载失败'; }
return JSON.stringify({ list: [vod] });
}
async function play(flag, id) {
if (/七猫/.test(flag)) {
return JSON.stringify({ parse: 0, url: id });
}
if (/百度/.test(flag)) {
const res = JSON.parse(await request(`https://api.jkyai.top/API/bddjss.php?video_id=${id}`));
if (res?.data?.qualities) {
const order = ["1080p", "sc", "sd"];
const qMap = { "1080p": "蓝光", "sc": "超清", "sd": "标清" };
const urls = [];
order.forEach(k => {
const q = res.data.qualities.find(x => x.quality === k);
if (q) urls.push(qMap[k], q.download_url);
});
return JSON.stringify({ parse: 0, url: urls });
}
}
if (/甜圈/.test(flag)) {
return JSON.stringify({ parse: 0, url: `https://mov.cenguigui.cn/duanju/api.php?video_id=${id}&type=mp4` });
}
if (/锦鲤/.test(flag)) {
try {
const html = await request(`${id}&auto=1`, { headers: { referer: 'https://www.jinlidj.com/' } });
const match = html.match(/let data\s*=\s*({[^;]*});/);
if (match) {
const data = JSON.parse(match[1]);
if (data.url) return JSON.stringify({ parse: 0, url: data.url });
}
} catch {}
}
if (/番茄/.test(flag)) {
try {
const res = JSON.parse(await request(`https://fqgo.52dns.cc/video?item_ids=${id}`));
if (res?.data?.[id]?.video_model) {
const model = JSON.parse(res.data[id].video_model);
const mainUrl = model?.video_list?.video_1?.main_url;
if (mainUrl) return JSON.stringify({ parse: 0, url: base64Decode(mainUrl) });
}
} catch {}
}
if (/软鸭/.test(flag)) {
const response = await request(`${aggConfig.platform.软鸭.host}/API/playlet/?video_id=${id}&quality=1080p`, { headers: aggConfig.headers.default });
const res = JSON.parse(response);
return JSON.stringify({ parse: 0, url: res.data?.video?.url || '' });
}
if (/围观/.test(flag)) {
try {
const ps = typeof id === 'string' ? JSON.parse(id) : id;
const urls = [];
if (ps?.super) urls.push("超清", ps.super);
if (ps?.high) urls.push("高清", ps.high);
if (ps?.normal) urls.push("流畅", ps.normal);
return JSON.stringify({ parse: 0, url: urls });
} catch { return JSON.stringify({ parse: 0, url: id }); }
}
return JSON.stringify({ parse: 0, url: id });
}
async function search(wd, quick, pg) {
const page = parseInt(pg) || 1;
const videos = [];
try {
const sign = await md5(`operation=2playlet_privacy=1search_word=${wd}${aggConfig.keys}`);
const url = `${aggConfig.platform.七猫.host}${aggConfig.platform.七猫.search}?search_word=${encodeURIComponent(wd)}&playlet_privacy=1&operation=2&sign=${sign}`;
const res = JSON.parse(await request(url, {
headers: { ...await getHeaderX(), ...aggConfig.headers.default },
timeout: aggConfig.search.timeout
}));
(res?.data?.list || []).forEach(i => {
if (i.title.toLowerCase().includes(wd.toLowerCase())) {
videos.push({
vod_id: `七猫@${encodeURIComponent(i.playlet_id)}`,
vod_name: i.title,
vod_pic: i.image_link,
vod_remarks: `七猫短剧|${i.total_episode_num}集`
});
}
});
} catch {}
const platforms = ['百度', '锦鲤', '番茄', '星芽', '西饭', '软鸭', '围观', '甜圈'];
for (const tid of platforms) {
const plat = aggConfig.platform[tid];
try {
let res, data;
if (tid === '百度') {
res = await request(`${plat.host}${plat.search.replace('**', encodeURIComponent(wd)).replace('fypage', page)}`);
data = (JSON.parse(res)?.data || []).map(i => ({ vod_id: `百度@${i.id}`, vod_name: i.title, vod_pic: i.cover, vod_remarks: `百度短剧|更新至${i.totalChapterNum}集` }));
} else if (tid === '锦鲤') {
res = await request(plat.host + plat.search, { method: 'POST', body: JSON.stringify({ page, limit: 30, keyword: wd }) });
data = (JSON.parse(res)?.data?.list || []).map(i => ({ vod_id: `锦鲤@${i.vod_id}`, vod_name: i.vod_name, vod_pic: i.vod_pic, vod_remarks: `锦鲤短剧|${i.vod_total}集` }));
} else if (tid === '番茄') {
res = await request(`${plat.search}?keyword=${encodeURIComponent(wd)}&page=${page}`);
data = (JSON.parse(res)?.data || []).map(i => ({ vod_id: `番茄@${i.series_id}`, vod_name: i.title, vod_pic: i.cover, vod_remarks: `番茄短剧|${i.sub_title}` }));
} else if (tid === '星芽') {
const headers = await getXingyaHeaders();
res = await request(plat.host + plat.search, { method: 'POST', headers, body: JSON.stringify({ text: wd }) });
data = (JSON.parse(res)?.data?.theater?.search_data || []).map(i => ({ vod_id: `星芽@${plat.host}${plat.url2}?theater_parent_id=${i.id}`, vod_name: i.title, vod_pic: i.cover_url, vod_remarks: `星芽短剧|${i.total}集 播放:${i.play_amount_str}` }));
} else if (tid === '西饭') {
const ts = Math.floor(Date.now() / 1000);
const url = `${plat.host}${plat.search}?reqType=search&offset=${(page - 1) * 30}&keyword=${encodeURIComponent(wd)}&quickEngineVersion=-1&scene=`;
res = await request(url);
data = (JSON.parse(res)?.result?.elements || []).map(vod => {
const dj = vod.duanjuVo || {};
return { vod_id: `西饭@${dj.duanjuId}#${dj.source}`, vod_name: dj.title, vod_pic: dj.coverImageUrl, vod_remarks: `西饭短剧|${dj.total}集` };
});
} else if (tid === '软鸭') {
res = await request(`${plat.host}${plat.search}/?keyword=${encodeURIComponent(wd)}&page=${page}`);
data = (JSON.parse(res)?.data || []).map(i => {
const purl = `${i.title}@${i.cover}@${i.author}@${i.type}@${i.desc}@${i.book_id}`;
return { vod_id: `软鸭@${encodeURIComponent(purl)}`, vod_name: i.title, vod_pic: i.cover, vod_remarks: `软鸭短剧|${i.type}` };
});
} else if (tid === '围观') {
res = await request(`${plat.host}${plat.search}`, {
method: 'POST',
body: JSON.stringify({ audience: "", page, pageSize: 30, searchWord: wd, subject: "" })
});
data = (JSON.parse(res)?.data || []).map(i => ({ vod_id: `围观@${i.oneId}`, vod_name: i.title, vod_pic: i.vertPoster, vod_remarks: `围观短剧|集数:${i.episodeCount} 播放:${i.viewCount}` }));
} else if (tid === '甜圈') {
const url = `${plat.host}${plat.search}=${encodeURIComponent(wd)}&offset=${page}`;
res = await request(url);
data = (JSON.parse(res)?.data || []).map(i => ({
vod_id: `甜圈@${i.book_id}`,
vod_name: i.title,
vod_pic: i.cover,
vod_remarks: `甜圈短剧|${i.sub_title || '无简介'}`
}));
}
if (data) videos.push(...data.filter(v => v.vod_name?.toLowerCase().includes(wd.toLowerCase())));
} catch {}
}
return JSON.stringify({
list: videos,
page,
pagecount: page + 1,
limit: videos.length,
total: videos.length * (page + 1)
});
}
export function __jsEvalReturn() {
return { init, home, homeVod, category, detail, play, proxy: null, search };
}
-552
View File
@@ -1,552 +0,0 @@
# coding=utf-8
# !/usr/bin/python
"""
作者 精彩一瞬间 内容均从互联网收集而来 仅供交流学习使用 严禁用于商业用途 请于24小时内删除
====================Diudiumiao====================
"""
from Crypto.Util.Padding import unpad
from Crypto.Util.Padding import pad
from urllib.parse import urlparse
from urllib.parse import unquote
from Crypto.Cipher import ARC4
from urllib.parse import quote
from base.spider import Spider
from Crypto.Cipher import AES
from datetime import datetime
from bs4 import BeautifulSoup
from base64 import b64decode
import concurrent.futures
import urllib.request
import urllib.parse
import datetime
import binascii
import requests
import hashlib
import base64
import json
import time
import hmac
import sys
import re
import os
sys.path.append('..')
xurl = "https://www.wasu.cn"
headerx = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36'
}
headerz = {
'accept': '*/*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'cache-control': 'no-cache',
'origin': xurl,
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': xurl,
'sec-ch-ua': '"Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',
}
class Spider(Spider):
def getName(self):
return "精彩"
def init(self, extend):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def homeVideoContent(self):
pass
def homeContent(self, filter):
result = {}
result = {"class": [{"type_id": "961", "type_name": "电影"},
{"type_id": "962", "type_name": "剧集"},
{"type_id": "963", "type_name": "少儿"},
{"type_id": "965", "type_name": "栏目"},
{"type_id": "966", "type_name": "新闻"}],
"list": [],
"filters": {"961": [{"key": "地区",
"name": "地区",
"value": [{"n": "全部", "v": ""},
{"n": "内地", "v": "内地"},
{"n": "港台", "v": "港台"},
{"n": "欧美", "v": "欧美"},
{"n": "日韩", "v": "日韩"},
{"n": "泰国", "v": "泰国"},
{"n": "其他", "v": "其他"}]},
{"key": "类型",
"name": "类型",
"value": [{"n": "全部", "v": ""},
{"n": "动作", "v": "动作"},
{"n": "科幻", "v": "科幻"},
{"n": "惊悚", "v": "惊悚"},
{"n": "冒险", "v": "冒险"},
{"n": "剧情", "v": "剧情"},
{"n": "励志", "v": "励志"},
{"n": "爱情", "v": "爱情"},
{"n": "喜剧", "v": "喜剧"},
{"n": "家庭", "v": "家庭"},
{"n": "历史", "v": "历史"},
{"n": "魔幻", "v": "魔幻"},
{"n": "恐怖", "v": "恐怖"},
{"n": "战争", "v": "战争"},
{"n": "武侠", "v": "武侠"}]},
{"key": "年代",
"name": "年代",
"value": [{"n": "全部", "v": ""},
{"n": "2026", "v": "2026"},
{"n": "2025", "v": "2025"},
{"n": "2024", "v": "2024"},
{"n": "2023", "v": "2023"},
{"n": "2022", "v": "2022"},
{"n": "2021", "v": "2021"},
{"n": "2020", "v": "2020"},
{"n": "2019", "v": "2019"},
{"n": "2018", "v": "2018"},
{"n": "2017", "v": "2017"},
{"n": "2016", "v": "2016"},
{"n": "2015", "v": "2015"},
{"n": "2014", "v": "2014"},
{"n": "2013", "v": "2013"},
{"n": "2012", "v": "2012"},
{"n": "2011", "v": "2011"},
{"n": "2010", "v": "2010"}]}],
"962": [{"key": "地区",
"name": "地区",
"value": [{"n": "全部", "v": ""},
{"n": "内地", "v": "内地"},
{"n": "港台", "v": "港台"},
{"n": "日韩", "v": "日韩"},
{"n": "欧美", "v": "欧美"},
{"n": "泰国", "v": "泰国"},
{"n": "其他", "v": "其他"}]},
{"key": "类型",
"name": "类型",
"value": [{"n": "全部", "v": ""},
{"n": "都市", "v": "都市"},
{"n": "爱情", "v": "爱情"},
{"n": "短剧", "v": "短剧"}, {"n": "战争", "v": "战争"},
{"n": "家庭", "v": "家庭"},
{"n": "悬疑", "v": "悬疑"},
{"n": "古装", "v": "古装"}, {"n": "谍战", "v": "谍战"},
{"n": "喜剧", "v": "喜剧"},
{"n": "农村", "v": "农村"},
{"n": "刑侦", "v": "刑侦"},
{"n": "武侠", "v": "武侠"},
{"n": "历史", "v": "历史"}]},
{"key": "年代",
"name": "年代",
"value": [{"n": "全部", "v": ""},
{"n": "2026", "v": "2026"},
{"n": "2025", "v": "2025"},
{"n": "2024", "v": "2024"},
{"n": "2023", "v": "2023"},
{"n": "2022", "v": "2022"},
{"n": "2021", "v": "2021"},
{"n": "2020", "v": "2020"},
{"n": "2019", "v": "2019"},
{"n": "2018", "v": "2018"},
{"n": "2017", "v": "2017"},
{"n": "2016", "v": "2016"},
{"n": "2015", "v": "2015"},
{"n": "2014", "v": "2014"},
{"n": "2013", "v": "2013"},
{"n": "2012", "v": "2012"},
{"n": "2011", "v": "2011"},
{"n": "2010", "v": "2010"}]}],
"963": [{"key": "地区",
"name": "地区",
"value": [{"n": "全部", "v": ""},
{"n": "内地", "v": "内地"},
{"n": "日韩", "v": "日韩"},
{"n": "欧美", "v": "欧美"},
{"n": "港台", "v": "港台"},
{"n": "其他", "v": "其他"}]},
{"key": "类型",
"name": "类型",
"value": [{"n": "全部", "v": ""},
{"n": "动作", "v": "动作"},
{"n": "冒险", "v": "冒险"},
{"n": "益智", "v": "益智"},
{"n": "亲子", "v": "亲子"},
{"n": "热血", "v": "热血"},
{"n": "剧情", "v": "剧情"},
{"n": "魔幻", "v": "魔幻"},
{"n": "励志", "v": "励志"},
{"n": "机战", "v": "机战"},
{"n": "搞笑", "v": "搞笑"},
{"n": "科幻", "v": "科幻"},
{"n": "治愈", "v": "治愈"},
{"n": "儿歌", "v": "儿歌"},
{"n": "教育", "v": "教育"},
{"n": "校园", "v": "校园"},
{"n": "童话", "v": "童话"},
{"n": "推理", "v": "推理"},
{"n": "怀旧", "v": "怀旧"},
{"n": "宠物", "v": "宠物"},
{"n": "舞蹈", "v": "舞蹈"}]},
{"key": "年代",
"name": "年代",
"value": [{"n": "全部", "v": ""},
{"n": "2026", "v": "2026"},
{"n": "2025", "v": "2025"},
{"n": "2024", "v": "2024"},
{"n": "2023", "v": "2023"},
{"n": "2022", "v": "2022"},
{"n": "2021", "v": "2021"},
{"n": "2020", "v": "2020"},
{"n": "2019", "v": "2019"},
{"n": "2018", "v": "2018"},
{"n": "2017", "v": "2017"},
{"n": "2016", "v": "2016"},
{"n": "2015", "v": "2015"},
{"n": "2014", "v": "2014"},
{"n": "2013", "v": "2013"},
{"n": "2012", "v": "2012"},
{"n": "2011", "v": "2011"},
{"n": "2010", "v": "2010"}]}],
"965": [{"key": "地区",
"name": "地区",
"value": [{"n": "全部", "v": ""},
{"n": "内地", "v": "内地"},
{"n": "欧美", "v": "欧美"}]},
{"key": "类型",
"name": "类型",
"value": [{"n": "全部", "v": ""},
{"n": "文化", "v": "文化"},
{"n": "纪实", "v": "纪实"},
{"n": "访谈", "v": "访谈"},
{"n": "历史", "v": "历史"},
{"n": "美食", "v": "美食"},
{"n": "旅游", "v": "旅游"},
{"n": "时尚", "v": "时尚"},
{"n": "情感", "v": "情感"},
{"n": "生活", "v": "生活"},
{"n": "真人秀", "v": "真人秀"}]},
{"key": "年代",
"name": "年代",
"value": [{"n": "全部", "v": ""},
{"n": "2026", "v": "2026"},
{"n": "2025", "v": "2025"},
{"n": "2024", "v": "2024"},
{"n": "2023", "v": "2023"},
{"n": "2022", "v": "2022"},
{"n": "2021", "v": "2021"},
{"n": "2020", "v": "2020"},
{"n": "2019", "v": "2019"},
{"n": "2018", "v": "2018"},
{"n": "2017", "v": "2017"},
{"n": "2016", "v": "2016"},
{"n": "2015", "v": "2015"},
{"n": "2014", "v": "2014"},
{"n": "2013", "v": "2013"},
{"n": "2012", "v": "2012"},
{"n": "2011", "v": "2011"},
{"n": "2010", "v": "2010"}]}],
"966": [{"key": "类型",
"name": "类型",
"value": [{"n": "全部", "v": ""},
{"n": "国内视野", "v": "国内视野"},
{"n": "国际纵览", "v": "国际纵览"},
{"n": "军事话题", "v": "军事话题"},
{"n": "社会百态", "v": "社会百态"},
{"n": "央视频", "v": "央视频"}]}]}}
return result
def generate_x_sign(self, secret_b64):
secret_key = self.decode_secret_key(secret_b64)
data = self.get_data_string()
signature = self.compute_signature(secret_key, data)
x_sign = self.encode_signature(signature)
return x_sign
def decode_secret_key(self, secret_b64):
return base64.b64decode(secret_b64)
def get_data_string(self):
return "{}"
def compute_signature(self, secret_key, data):
return hmac.new(secret_key, data.encode('utf-8'), hashlib.sha256).digest()
def encode_signature(self, signature):
return base64.b64encode(signature).decode('utf-8')
def get_current_app_key(self, xurl, headerx):
resp = self.fetch_index_page(xurl, headerx)
js_path = self.extract_js_path(resp.text)
js_url = f"{xurl}{js_path}"
js_content = self.fetch_js_content(js_url, headerx)
target_key_b64 = self.extract_target_key(js_content)
return target_key_b64
def fetch_index_page(self, xurl, headerx):
resp = requests.get(xurl, headers=headerx)
resp.raise_for_status()
return resp
def extract_js_path(self, html_content):
js_path_pattern = r'src="(/[\d\.]+/assets/js/index-[\w\.-]+\.js)"'
match = re.search(js_path_pattern, html_content)
return match.group(1)
def fetch_js_content(self, js_url, headerx):
js_resp = requests.get(js_url, headers=headerx)
js_resp.raise_for_status()
return js_resp.text
def extract_target_key(self, js_content):
key_pattern = r'const \w+="([^"]+)",\w+="([^"]+)",\w+="([^"]+)";'
key_match = re.search(key_pattern, js_content)
return key_match.group(2)
def get_headers(self, sign1, xurl):
return {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'cache-control': 'no-cache',
'launchchannel': 'web_channel',
'origin': xurl,
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': xurl,
'sec-ch-ua': '"Microsoft Edge";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'siteid': '1000101',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0',
'x-sign': sign1,
}
def categoryContent(self, cid, pg, filter, ext):
secret_b64 = self.get_current_app_key(xurl, headerx)
sign1 = self.generate_x_sign(secret_b64)
page = self.get_page_number(pg)
NdType, DqType, LxType = self.extract_filter_types(ext)
headers = self.get_headers(sign1, xurl)
params = self.build_category_params(cid, page, NdType, DqType, LxType)
data = self.fetch_category_data(params, headers)
videos = self.parse_category_videos(data)
return self.build_category_result(videos, pg)
def get_page_number(self, pg):
return int(pg) if pg else 1
def extract_filter_types(self, ext):
NdType = ext.get('年代', '全部')
DqType = ext.get('地区', '全部')
LxType = ext.get('类型', '全部')
return NdType, DqType, LxType
def build_category_params(self, cid, page, NdType, DqType, LxType):
return {'functionName': 'getNewsSearchedByCondition','nodeId': cid,'nodeTag': LxType,'yearTag': NdType,'countryTag': DqType,'orderType': '0','pageSize': '40','page': page,'keyword': '','siteId': '1000101',}
def fetch_category_data(self, params, headers):
detail = requests.get('https://ups.5g.wasu.tv/rmp-user-suggest/1000101/hzhs/searchServlet', params=params,headers=headers)
detail.encoding = "utf-8"
return detail.json()
def parse_category_videos(self, data):
videos = []
for vod in data['data']:
videos.append(self.parse_category_video(vod))
return videos
def parse_category_video(self, vod):
return {"vod_id": f"{vod['nodeId']}@{vod['newsId']}","vod_name": vod['title'],"vod_pic": vod['hPic'],"vod_year": vod.get('pubTime', '暂无日期'),"vod_remarks": vod.get('episodeDesc', '暂无备注')}
def build_category_result(self, videos, pg):
result = {'list': videos}
result['page'] = pg
result['pagecount'] = 9999
result['limit'] = 90
result['total'] = 999999
return result
def detailContent(self, ids):
did = ids[0]
secret_b64 = self.get_current_app_key(xurl, headerx)
sign1 = self.generate_x_sign(secret_b64)
fenge = did.split("@")
headers = self.get_headers(sign1, xurl)
params = self.build_detail_params(fenge)
data = self.fetch_detail_data(params, headers)
content = self.build_content(data)
director = self.extract_detail_field(data, 'director')
actor = self.extract_detail_field(data, 'actor')
remarks = self.extract_detail_field(data, 'episodeDesc')
year = self.extract_detail_field(data, 'pubTime')
area = self.extract_detail_field(data, 'countryTag')
bofang = self.build_play_url(data)
videos = [self.build_video_data(did, director, actor, remarks, year, area, content, bofang)]
return self.build_result(videos)
def build_detail_params(self, fenge):
return {'siteId': '1000101', 'functionName': 'getCurrentNews', 'nodeId': fenge[0], 'newsId': fenge[1],'platform': 'web',}
def fetch_detail_data(self, params, headers):
detail = requests.get('https://mcspapp.5g.wasu.tv/bvradio_app/hzhs/newsServlet', params=params, headers=headers)
detail.encoding = "utf-8"
return detail.json()
def build_content(self, data):
return '介绍剧情👉' + data.get('data', {}).get('newsAbstract', '')
def extract_detail_field(self, data, field_name):
return data.get('data', {}).get(field_name, '')
def build_play_url(self, data):
bofang = ''
for vod in data['data']['vodList']:
name = vod['title']
if len(vod['fileList']) > 1:
id = vod['fileList'][1]['playUrl']
else:
id = vod['fileList'][0]['playUrl']
bofang += name + '$' + id + '#'
return bofang[:-1]
def build_video_data(self, did, director, actor, remarks, year, area, content, bofang):
return {"vod_id": did, "vod_director": director, "vod_actor": actor, "vod_remarks": remarks, "vod_year": year, "vod_area": area, "vod_content": content, "vod_play_from": "华数", "vod_play_url": bofang}
def build_result(self, videos):
result = {}
result['list'] = videos
return result
def get_x_sign_for_post(self, secret_b64, playUrl):
secret_key = self.decode_secret_key(secret_b64)
payload_dict = self.build_payload_dict(playUrl)
data_string = self.serialize_payload(payload_dict)
signature = self.compute_hmac_signature(secret_key, data_string)
x_sign = self.encode_signature(signature)
return x_sign
def decode_secret_key(self, secret_b64):
return base64.b64decode(secret_b64)
def build_payload_dict(self, playUrl):
return {"playUrl": playUrl, "platform": "web"}
def serialize_payload(self, payload_dict):
return json.dumps(payload_dict, separators=(',', ':'), ensure_ascii=False)
def compute_hmac_signature(self, secret_key, data_string):
return hmac.new(secret_key, data_string.encode('utf-8'), hashlib.sha256).digest()
def encode_signature(self, signature):
return base64.b64encode(signature).decode('utf-8')
def playerContent(self, flag, id, vipFlags):
secret_b64 = self.get_current_app_key(xurl, headerx)
id = self.normalize_play_url(id)
sign2 = self.get_x_sign_for_post(secret_b64, id)
headers = self.get_headers(sign2, xurl)
json_data = self.build_request_json(id)
result = self.post_play_url_request(headers, json_data)
play_url = result['data']['playUrl']
return self.build_player_result(play_url)
def normalize_play_url(self, id):
return id.replace('.mp4', '/playlist.m3u8')
def build_request_json(self, playUrl):
return {'playUrl': playUrl, 'platform': 'web', }
def post_play_url_request(self, headers, json_data):
response = requests.post('https://mcspapp.5g.wasu.tv/thirdApiFile/file/getPlayUrl', headers=headers, json=json_data)
return response.json()
def build_player_result(self, play_url):
result = {}
result["parse"] = 0
result["playUrl"] = ''
result["url"] = play_url
result["header"] = headerz
return result
def searchContentPage(self, key, quick, pg):
page = self.get_page_number(pg)
secret_b64 = self.get_current_app_key(xurl, headerx)
sign1 = self.generate_x_sign(secret_b64)
headers = self.get_headers(sign1, xurl)
params = self.build_search_params(key, page)
data = self.fetch_search_data(params, headers)
videos = self.parse_search_videos(data)
return self.build_search_result(videos, pg)
def get_page_number(self, pg):
return int(pg) if pg else 1
def build_search_params(self, key, page):
return {'functionName': 'getNewsSearched', 'searchNewsType': '3,4,5', 'keyword': key, 'pageSize': 10, 'page': page, 'siteId': 1000101}
def fetch_search_data(self, params, headers):
detail = requests.get("https://ups.5g.wasu.tv/rmp-user-suggest/1000101/hzhs/searchServlet", params=params, headers=headers)
detail.encoding = "utf-8"
return detail.json()
def parse_search_videos(self, data):
videos = []
for vod in data['data']:
videos.append(self.parse_search_video(vod))
return videos
def parse_search_video(self, vod):
return {"vod_id": f"{vod['nodeId']}@{vod['newsId']}", "vod_name": vod['title'], "vod_pic": vod['hPic'], "vod_year": vod.get('pubTime', '暂无日期'), "vod_remarks": vod.get('episodeDesc', '暂无备注')}
def build_search_result(self, videos, pg):
result = {'list': videos}
result['page'] = pg
result['pagecount'] = 9999
result['limit'] = 90
result['total'] = 999999
return result
def searchContent(self, key, quick, pg="1"):
return self.searchContentPage(key, quick, '1')
def localProxy(self, params):
if params['type'] == "m3u8":
return self.proxyM3u8(params)
elif params['type'] == "media":
return self.proxyMedia(params)
elif params['type'] == "ts":
return self.proxyTs(params)
return None
-225
View File
@@ -1,225 +0,0 @@
# -*- coding: utf-8 -*-
# by @嗷呜
import json
import sys
import threading
import uuid
import requests
sys.path.append('..')
from base.spider import Spider
import time
from Crypto.Hash import MD5, SHA1
class Spider(Spider):
'''
配置示例:
{
"key": "xxxx",
"name": "xxxx",
"type": 3,
"api": ".所在路径/金牌.py",
"searchable": 1,
"quickSearch": 1,
"filterable": 1,
"changeable": 1,
"ext": {
"site": "https://www.jiabaide.cn,域名2,域名3"
}
},
'''
def init(self, extend=""):
if extend:
hosts=json.loads(extend)['site']
self.host = self.host_late(hosts)
pass
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
def homeContent(self, filter):
cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json()
fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json()
result = {}
classes = []
filters={}
for k in cdata['data']:
classes.append({
'type_name': k['typeName'],
'type_id': str(k['typeId']),
})
sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}]
for tid, d in fdata['data'].items():
current_sort_values = sort_values.copy()
if tid == '1':
del current_sort_values[0]
filters[tid] = [
{"key": "type", "name": "类型",
"value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]},
*([] if not d["plotList"] else [{"key": "v_class", "name": "剧情",
"value": [{"n": i["itemText"], "v": i["itemText"]}
for i in d["plotList"]]}]),
{"key": "area", "name": "地区",
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]},
{"key": "year", "name": "年份",
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]},
{"key": "lang", "name": "语言",
"value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]},
{"key": "sort", "name": "排序", "value": current_sort_values}
]
result['class'] = classes
result['filters'] = filters
return result
def homeVideoContent(self):
data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json()
data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json()
data=[]
for i in data1['data'].values():
data.extend(i['list'])
data.extend(data2['data'])
vods=self.getvod(data)
return {'list':vods}
def categoryContent(self, tid, pg, filter, extend):
params = {
"area": extend.get('area', ''),
"filterStatus": "1",
"lang": extend.get('lang', ''),
"pageNum": pg,
"pageSize": "30",
"sort": extend.get('sort', '1'),
"sortBy": "1",
"type": extend.get('type', ''),
"type1": tid,
"v_class": extend.get('v_class', ''),
"year": extend.get('year', '')
}
data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json()
result = {}
result['list'] = self.getvod(data['data']['list'])
result['page'] = pg
result['pagecount'] = 9999
result['limit'] = 90
result['total'] = 999999
return result
def detailContent(self, ids):
data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json()
vod=self.getvod([data['data']])[0]
vod['vod_play_from']='拾光有文才'
vod['vod_play_url'] = '#'.join(
f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in
vod['episodelist'])
vod.pop('episodelist', None)
return {'list':[vod]}
def searchContent(self, key, quick, pg="1"):
params = {
"keyword": key,
"pageNum": pg,
"pageSize": "8",
"sourceCode": "1"
}
data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json()
vods=self.getvod(data['data']['result']['list'])
return {'list':vods,'page':pg}
def playerContent(self, flag, id, vipFlags):
self.header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36',
'sec-ch-ua-platform': '"Windows"',
'DNT': '1',
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
'sec-ch-ua-mobile': '?0',
'Origin': self.host,
'Referer': f'{self.host}/'
}
ids=id.split('@@')
pdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id={ids[0]}&nid={ids[1]}",headers=self.getheaders({'clientType':'1','id': ids[0], 'nid': ids[1]})).json()
vlist=[]
for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']])
return {'parse':0,'url':vlist,'header':self.header}
def localProxy(self, param):
pass
def host_late(self, url_list):
if isinstance(url_list, str):
urls = [u.strip() for u in url_list.split(',')]
else:
urls = url_list
if len(urls) <= 1:
return urls[0] if urls else ''
results = {}
threads = []
def test_host(url):
try:
start_time = time.time()
response = requests.head(url, timeout=1.0, allow_redirects=False)
delay = (time.time() - start_time) * 1000
results[url] = delay
except Exception as e:
results[url] = float('inf')
for url in urls:
t = threading.Thread(target=test_host, args=(url,))
threads.append(t)
t.start()
for t in threads:
t.join()
return min(results.items(), key=lambda x: x[1])[0]
def md5(self, sign_key):
md5_hash = MD5.new()
md5_hash.update(sign_key.encode('utf-8'))
md5_result = md5_hash.hexdigest()
return md5_result
def js(self, param):
return '&'.join(f"{k}={v}" for k, v in param.items())
def getheaders(self, param=None):
if param is None:param = {}
t=str(int(time.time()*1000))
param['key']='cb808529bae6b6be45ecfab29a4889bc'
param['t']=t
sha1_hash = SHA1.new()
sha1_hash.update(self.md5(self.js(param)).encode('utf-8'))
sign = sha1_hash.hexdigest()
deviceid = str(uuid.uuid4())
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36',
'Accept': 'application/json, text/plain, */*',
'sign': sign,
't': t,
'deviceid':deviceid
}
return headers
def convert_field_name(self, field):
field = field.lower()
if field.startswith('vod') and len(field) > 3:
field = field.replace('vod', 'vod_')
if field.startswith('type') and len(field) > 4:
field = field.replace('type', 'type_')
return field
def getvod(self, array):
return [{self.convert_field_name(k): v for k, v in item.items()} for item in array]
-318
View File
@@ -1,318 +0,0 @@
/*
title: '星辰影院', author: '小可乐/v6.1.1'
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
"ext": {
"host": "xxxx", //站点网址
"timeout": 6000, //请求超时,单位毫秒
"catesSet": "电视剧&电影&综艺", //指定分类和顺序
"tabsSet": "土星&下载线1" //指定线路和顺序
}
*/
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36';
const DefHeader = {'User-Agent': MOBILE_UA};
var HOST;
var KParams = {
headers: {'User-Agent': MOBILE_UA},
timeout: 5000
};
async function init(cfg) {
try {
HOST = (cfg.ext?.host?.trim() || 'https://www.xcyycn.com').replace(/\/$/, '');
KParams.headers['Referer'] = HOST;
let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10);
if (parseTimeout > 0) {KParams.timeout = parseTimeout;}
KParams.catesSet = cfg.ext?.catesSet?.trim() || '';
KParams.tabsSet = cfg.ext?.tabsSet?.trim() || '';
KParams.resHtml = await request(HOST);
} catch (e) {
console.error('初始化参数失败:', e.message);
}
}
async function home(filter) {
try {
let resHtml = KParams.resHtml;
if (!resHtml) {throw new Error('源码为空');}
let typeArr = cutStr(resHtml, 'hl-nav-item£>', '</li>', '', false, 0, true).filter(flt => flt.includes('/v/'));
let classes = typeArr.map((it,idx) => {
let cName = cutStr(it, '>', '<', `分类${idx+1}`);
let cId = cutStr(it, '/v/', '.', `值${idx+1}`);
return {type_name: cName, type_id: cId};
});
if (KParams.catesSet) {classes = ctSet(classes, KParams.catesSet);}
let filters = {};
try {
const nameObj = {class: 'class,剧情', area: 'area,地区', lang: 'lang,语言', year: 'year,年份', letter: 'letter,字母', by: 'by,排序'};
const regObj = {class: /\d+---([^-]+)-/, area: /\/\d+-([^-]+)-/, lang: /\d+----([^-]+)-/, year: /-([^-]+)\./, letter: /\d+-----([^-]+)-/, by: /\d+--([^-]+)-/};
let resHtmlList = await Promise.all(
classes.map(async (it) => {
try {return await request(`${HOST}/vs/${it.type_id}-----------.html`);} catch (sErr) {return '';}
})
);
classes.forEach((it,idx) => {
let resfHtml = resHtmlList[idx];
if (resfHtml) {
let flValArr = cutStr(resfHtml, 'hl-filter-list', '</ul>', '', false, 0, true).slice(1);
filters[it.type_id] = Object.entries(nameObj).map(([nObjk, nObjv]) => {
let [kkey, kname] = nObjv.split(',');
let tgVal = flValArr.find(fv => regObj[kkey].test(fv)) ?? '';
if (kkey === 'by') {tgVal = cutStr(resfHtml, 'hl-rb-title', '</div>', '', false);}
let tgValArr = cutStr(tgVal, '<a', '/a>', '', false, 0, true);
let tValArr = kkey !== 'by' ? tgValArr.slice(1) : tgValArr;
let kvalue = tValArr.map(el => {
let n = cutStr(el, '>', '<', '空白');
let v = n;
if (kkey === 'by') {v = el.match(regObj[kkey])?.[1] ?? '';}
return {n: n, v: v};
});
if (kkey !== 'by') {kvalue.unshift({n: '全部', v: ''});}
return {key: kkey, name: kname, value: kvalue};
}).filter(flt => flt.key && flt.value.length > 1);
}
});
} catch (e) {
filters = {}
}
return JSON.stringify({class: classes, filters: filters});
} catch (e) {
console.error('获取分类失败:', e.message);
return JSON.stringify({class: [], filters: {}});
}
}
async function homeVod() {
try {
let resHtml = KParams.resHtml;
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS});
} catch (e) {
console.error('推荐页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function category(tid, pg, filter, extend) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let fl = extend || {};
let cateUrl = `${HOST}/vs/${fl.cateId || tid}-${fl.area ?? ''}-${fl.by ?? ''}-${fl.class ?? ''}-${fl.lang ?? ''}-${fl.letter ?? ''}---${pg}---${fl.year ?? ''}.html`;
let resHtml = await request(cateUrl);
let VODS = getVodList(resHtml);
let limit = VODS.length;
let pagecount = cutStr(resHtml, 'hl-page-total£/', '页', '1');
pagecount = Number(pagecount);
return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: limit, total: limit*pagecount});
} catch (e) {
console.error('类别页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
async function search(wd, quick, pg) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let searchUrl = `${HOST}/s${wd}/page/${pg}.html`;
let resHtml = await request(searchUrl);
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300});
} catch (e) {
console.error('搜索页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
function getVodList(khtml) {
try {
if (!khtml) {throw new Error('源码为空');}
let kvods = [];
let listArr = cutStr(khtml, 'hl-lazy', '</a>', '', false, 0, true).filter(flt => flt.includes('remarks'));
for (let it of listArr) {
let kname = cutStr(it, 'title="', '"', '名称');
let kpic = cutStr(it, 'data-original="', '"', '图片');
let kremarks = cutStr(it, 'remarks">', '</', '状态');
let kid = cutStr(it, 'href="', '"');
if (kid) {
kvods.push({
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
vod_id: `${kid}@${kname}@${kpic}@${kremarks}`
});
}
}
return kvods;
} catch (e) {
console.error(`生成视频列表失败:`, e.message);
return [];
}
}
async function detail(ids) {
try {
let [id, kname, kpic, kremarks] = ids.split('@');
let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id;
let resHtml = await request(detailUrl);
if (!resHtml) {throw new Error('源码为空');}
let intros = cutStr(resHtml, '"clearfix">', '</ul>', '', false);
let [ktabs, kurls] = [[], []];
let zx_tabs = cutStr(resHtml, '<span class="hl-from', '/span>', '', false, 0, true).map((it,idx) => cutStr(it, '>', '<', `在线${idx+1}`) );
ktabs.push(...zx_tabs);
let zx_urls = cutStr(resHtml, 'hl-plays-list">', '</ul>', '', false, 0, true).map((item,idx) => cutStr(item, '<li', '</li>', '', false, 0, true).map(it => { return cutStr(it, '>', '</a>', 'noEpi') + '$' + HOST + cutStr(it, 'href="', '"', 'noUrl'); }).join('#') );
kurls.push(...zx_urls);
let xzArr = cutStr(resHtml, 'hl-downs-list hl', '</ul>', '', false, 0, true);
if (xzArr[0]) {
xzArr.forEach((item,idx) => {
let siglUrl = cutStr(item, 'down_url', '>', '', false, 0, true).map(it => `${cutStr(it, 'file_name="', '"', 'noEpi')}$${cutStr(it, 'value="', '"', 'noUrl')}` ).join('#');
ktabs.push(`下载线${idx+1}`);
kurls.push(siglUrl);
});
}
if (KParams.tabsSet) {
let ktus = ktabs.map((it, idx) => { return {type_name: it, type_value: kurls[idx]} });
ktus = ctSet(ktus, KParams.tabsSet);
ktabs = ktus.map(it => it.type_name);
kurls = ktus.map(it => it.type_value);
}
let VOD = {
vod_id: detailUrl,
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
type_name: cutStr(intros, '类型:', '</li>', '类型'),
vod_year: cutStr(intros, '年份:', '</li>', '1000'),
vod_area: cutStr(intros, '地区:', '</li>', '地区'),
vod_lang: cutStr(intros, '语言:', '</li>', '语言'),
vod_director: cutStr(intros, '导演:', '</li>', '导演'),
vod_actor: cutStr(intros, '主演:', '</li>', '主演'),
vod_content: cutStr(intros, '简介:', '</li>', kname),
vod_play_from: ktabs.join('$$$'),
vod_play_url: kurls.join('$$$')
};
return JSON.stringify({list: [VOD]});
} catch (e) {
console.error('详情页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function play(flag, ids, flags) {
try {
let kp = 0, kurl = '';
if (/下载/.test(flag)) {
kurl = ids;
} else {
let resHtml = await request(ids);
let codeObj = safeParseJSON(cutStr(resHtml, 'var player_£=', '<', '', false));
kurl = codeObj?.url ?? '';
if (!/^http/.test(kurl)) {
kurl = ids;
kp = 1;
}
}
return JSON.stringify({jx: 0, parse: kp, url: kurl, header: DefHeader});
} catch (e) {
console.error('播放失败:', e.message);
return JSON.stringify({jx: 0, parse: 0, url: '', header: {}});
}
}
function ctSet(kArr, setStr) {
try {
if (!Array.isArray(kArr) || kArr.length === 0 || typeof setStr !== 'string' || !setStr) { throw new Error('第一参数需为非空数组,第二参数需为非空字符串'); }
const set_arr = [...kArr];
const arrNames = setStr.split('&');
const filtered_arr = arrNames.map(item => set_arr.find(it => it.type_name === item)).filter(Boolean);
return filtered_arr.length? filtered_arr : [set_arr[0]];
} catch (e) {
console.error('ctSet 执行异常:', e.message);
return kArr;
}
}
function safeParseJSON(jStr){
try {return JSON.parse(jStr);} catch(e) {return null;}
}
function cutStr(str, prefix = '', suffix = '', defVal = '', clean = true, i = 0, all = false) {
try {
if (typeof str !== 'string') {throw new Error('被截取对象必须为字符串');}
const cleanStr = cs => String(cs).replace(/<[^>]*?>/g, ' ').replace(/(&nbsp;|[\u0020\u00A0\u3000\s])+/g, ' ').trim().replace(/\s+/g, ' ');
const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&');
let pre = esc(prefix).replace(/£/g, '[^]*?'), end = esc(suffix);
const regex = new RegExp(`${pre || '^'}([^]*?)${end || '$'}`, 'g');
const matchIter = str.matchAll(regex);
if (all) {
let matchArr = [...matchIter];
if (!matchArr.length) {return [defVal];}
return matchArr.map(ela => ela[1] !== undefined ? (clean ? cleanStr(ela[1]) : ela[1]) : defVal);
}
const idx = parseInt(i, 10);
if (isNaN(idx)) {throw new Error('序号必须为整数');}
let tgResult, matchIdx = 0;
if (idx >= 0) {
for (let elt of matchIter) {
if (matchIdx++ === idx) {
tgResult = elt[1];
break;
}
}
} else {
let absI = Math.abs(idx), ringBuf = new Array(absI), ringPtr = 0, ringCnt = 0;
for (let elt of matchIter) {
ringBuf[ringPtr] = elt[1];
ringPtr = (ringPtr + 1) % absI;
ringCnt = Math.min(ringCnt + 1, absI);
matchIdx++;
}
tgResult = (matchIdx >= absI && ringCnt > 0) ? ringBuf[ringPtr % ringCnt] : undefined;
}
return tgResult !== undefined ? (clean ? (cleanStr(tgResult) || defVal) : tgResult) : defVal;
} catch (e) {
console.error(`字符串截取错误:`, e.message);
return all ? ['cutErr'] : 'cutErr';
}
}
async function request(reqUrl, options = {}) {
try {
if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); }
if (typeof options !== 'object' || Array.isArray(options) || options === null) { throw new Error('options类型需为非null对象'); }
options.method = options.method?.toUpperCase() || 'GET';
if (['GET', 'HEAD'].includes(options.method)) {
delete options.body;
delete options.data;
delete options.postType;
}
let {headers, timeout, ...restOpts} = options;
const optObj = {
headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers,
timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout,
...restOpts
};
const res = await req(reqUrl, optObj);
if (options.withHeaders) {
const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {};
const resWithHeaders = { ...resHeaders, body: res?.content ?? '' };
return JSON.stringify(resWithHeaders);
}
return res?.content ?? '';
} catch (e) {
console.error(`${reqUrl}→请求失败:`, e.message);
return options?.withHeaders ? JSON.stringify({ body: '' }) : '';
}
}
export function __jsEvalReturn() {
return {
init,
home,
homeVod,
category,
search,
detail,
play,
proxy: null
};
}
-250
View File
@@ -1,250 +0,0 @@
/*
title: '月光影视', author: '小可乐/v5.12.1'
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
"ext": {
"host": "xxxx", //站点网址
"timeout": 6000 //请求超时,单位毫秒
}
*/
var HOST;
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36';
const DefHeader = {'User-Agent': MOBILE_UA};
const KParams = {
headers: {'User-Agent': MOBILE_UA},
timeout: 5000
};
async function init(cfg) {
try {
let host = cfg.ext?.host?.trim() || 'https://www.dzwhs.com';
HOST = host.replace(/\/$/, '');
KParams.headers['Referer'] = HOST;
let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10);
KParams.timeout = parseTimeout > 0 ? parseTimeout : 5000;
KParams.resHtml = await request(HOST);
} catch (e) {
console.error('初始化参数失败:', e.message);
}
}
async function home(filter) {
try {
let resHtml = KParams.resHtml;
if (!resHtml) {throw new Error('源码为空');}
let classes = cutStr(resHtml, '/zwhstp', '/a>', '', false, 1, true).map(it => {
let cName = cutStr(it, '>', '<', '分类名');
let cId = cutStr(it, '/', '.', '分类值');
return {type_name: cName, type_id: cId};
});
let filters = {
"1":[
{"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"动作片","v":"6"},{"n":"喜剧片","v":"7"},{"n":"爱情片","v":"8"},{"n":"科幻片","v":"9"},{"n":"恐怖片","v":"10"},{"n":"剧情片","v":"11"},{"n":"战争片","v":"12"},{"n":"纪录片","v":"13"},{"n":"悬疑片","v":"14"},{"n":"犯罪片","v":"15"},{"n":"奇幻片","v":"16"},{"n":"动画片","v":"31"},{"n":"预告片","v":"32"}]}
],
"2":[
{"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"国产剧","v":"17"},{"n":"港台剧","v":"18"},{"n":"日韩剧","v":"20"},{"n":"欧美剧","v":"21"},{"n":"海外剧","v":"22"}]}
],
"3":[
{"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"大陆综艺","v":"23"},{"n":"日韩综艺","v":"24"},{"n":"欧美综艺","v":"25"},{"n":"港台综艺","v":"26"}]}
],
"4":[
{"key":"cateId","name":"类型","value":[{"n":"全部","v":"全部"},{"n":"国产动漫","v":"27"},{"n":"日韩动漫","v":"28"},{"n":"欧美动漫","v":"29"},{"n":"其他动漫","v":"30"}]}
]
};
return JSON.stringify({class: classes, filters: filters});
} catch (e) {
console.error('获取分类失败:', e.message);
return JSON.stringify({class: [], filters: {}});
}
}
async function homeVod() {
try {
let resHtml = KParams.resHtml;
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS});
} catch (e) {
console.error('推荐页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function category(tid, pg, filter, extend) {
try {
pg = parseInt(pg, 10);
pg = pg > 0 ? pg : 1;
let cateUrl = `${HOST}/zwhstp/${extend?.cateId ?? tid}-${pg}.html`;
let resHtml = await request(cateUrl);
let VODS = getVodList(resHtml);
let pagecount = 999;
return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: 30, total: 30*pagecount});
} catch (e) {
console.error('类别页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
async function search(wd, quick, pg) {
try {
pg = parseInt(pg, 10);
pg = pg > 0 ? pg : 1;
let searchUrl = `${HOST}/zwhstp/id.html?wd=${wd}&page=${pg}`;
let resHtml = await request(searchUrl);
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300});
} catch (e) {
console.error('搜索页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
function getVodList(khtml) {
try {
if (!khtml) {throw new Error('源码为空');}
let kvods = [];
let listArr = cutStr(khtml, 'lazyload"', '/a>', '', false, 1, true);
for (let it of listArr) {
let kname = cutStr(it, 'title="', '"', '名称');
let kpic = cutStr(it, 'data-original="', '"', '图片');
let kremarks = cutStr(it, 'text-right">', '<', '状态');
kvods.push({
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
vod_id: `${cutStr(it, 'href="', '"', 'Id')}@${kname}@${kpic}@${kremarks}`
});
}
return kvods;
} catch (e) {
console.error(`生成视频列表失败:`, e.message);
return [];
}
}
async function detail(ids) {
try {
let [id, kname, kpic, kremarks] = ids.split('@');
let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id;
let resHtml = await request(detailUrl);
if (!resHtml) {throw new Error('源码为空');}
let intros = cutStr(resHtml, 'stui-content col-pd', 'play-btn', '', false);
let ktabs = cutStr(resHtml, 'pull-right"></span>', '/h3>', '', false, 1, true).map((it,idx) => cutStr(it, 'title">', '<', `线-${idx+1}`));
let kurls = cutStr(resHtml, '"stui-content__playlist', '</ul>', '', false, 1, true).map(item => {
let kurl = cutStr(item, '<a', '/a>', '', false, 1, true).map(it => { return cutStr(it, '>', '<', 'noEpi') + '$' + cutStr(it, 'href="', '"', 'noUrl'); });
return kurl.join('#');
});
let VOD = {
vod_id: detailUrl,
vod_name: kname,
vod_pic: kpic,
type_name: cutStr(intros, '类型:', '<span', '类型'),
vod_remarks: kremarks,
vod_year: cutStr(intros, '年份:', '</p>', '1000'),
vod_area: cutStr(intros, '地区:', '<span', '地区'),
vod_lang: '语言',
vod_director: cutStr(intros, '导演:', '</p>', '导演'),
vod_actor: cutStr(intros, '主演:', '</p>', '主演'),
vod_content: cutStr(intros, 'detail-content£>', '</span>', '简介'),
vod_play_from: ktabs.join('$$$'),
vod_play_url: kurls.join('$$$')
};
return JSON.stringify({list: [VOD]});
} catch (e) {
console.error('详情页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function play(flag, ids, flags) {
try {
let playUrl = !/^http/.test(ids) ? `${HOST}${ids}` : ids;
let kp = 0;
let resHtml = await request(playUrl);
let kcode = safeParseJSON(cutStr(resHtml, 'var player_£=', '<', '', false));
let kurl = kcode?.url ?? '';
if (!/m3u8|mp4|mkv/.test(kurl)) {
kp = 1;
kurl = playUrl;
}
return JSON.stringify({jx: 0, parse: kp, url: kurl, header: DefHeader});
} catch (e) {
console.error('播放失败:', e.message);
return JSON.stringify({jx: 0, parse: 0, url: '', header: {}});
}
}
function cutStr(str, prefix = '', suffix = '', defaultVal = 'cutFaile', clean = true, i = 1, all = false) {
try {
if (!str || typeof str !== 'string') {throw new Error('被截取对象需为非空字符串');}
const dealStr = ds => String(ds).replace(/<[^>]*?>/g, ' ').replace(/(&nbsp;|\u00A0|\s)+/g, ' ').trim().replace(/\s+/g, ' ');
const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&');
let pre = esc(prefix).replace(/£/g, '[^]*?');
let end = esc(suffix);
let regex = new RegExp(`${pre ? pre : '^'}([^]*?)${end ? end : '$'}`, 'g');
let matchArr = [...str.matchAll(regex)];
if (all) {
return matchArr.map(it => {
const val = it[1] ?? defaultVal;
return clean && val !== defaultVal ? dealStr(val) : val;
});
}
i = parseInt(i, 10);
if (isNaN(i) || i < 1) {throw new Error('序号需为大于0的整数');}
i = i - 1;
if (i >= matchArr.length) {throw new Error('序号越界');}
let result = matchArr[i][1] ?? defaultVal;
return clean && result !== defaultVal ? dealStr(result) : result;
} catch (e) {
console.error(`字符串截取失败:`, e.message);
return all ? ['cutErr'] : 'cutErr';
}
}
function safeParseJSON(jStr){
try {return JSON.parse(jStr);} catch(e) {return null;}
}
async function request(reqUrl, options = {}) {
try {
if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); }
if (typeof options !== 'object' || Array.isArray(options) || !options) { throw new Error('options类型需为非null对象'); }
options.method = options.method?.toLowerCase() || 'get';
if (['get', 'head'].includes(options.method)) {
delete options.data;
delete options.postType;
} else {
options.data = options.data ?? '';
options.postType = options.postType?.toLowerCase() || 'form';
}
let {headers, timeout, charset, toBase64 = false, ...restOpts } = options;
const optObj = {
headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers,
timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout,
charset: charset?.toLowerCase() || 'utf-8',
buffer: toBase64 ? 2 : 0,
...restOpts
};
const res = await req(reqUrl, optObj);
if (options.withHeaders) {
const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {};
const resWithHeaders = { ...resHeaders, body: res?.content ?? '' };
return JSON.stringify(resWithHeaders);
}
return res?.content ?? '';
} catch (e) {
console.error(`${reqUrl}→请求失败:`, e.message);
return options?.withHeaders ? JSON.stringify({ body: '' }) : '';
}
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
search: search,
detail: detail,
play: play,
proxy: null
};
}
-429
View File
@@ -1,429 +0,0 @@
if (typeof Object.assign !== 'function') {
Object.assign = function() {
let target = arguments[0];
for (let i = 1; i < arguments.length; i++) {
let source = arguments[i];
for (let key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
}
// 通用免嗅探播放
let common_lazy = `js:
let html = request(input);
let hconf = html.match(/r player_.*?=(.*?)</)[1];
let json = JSON5.parse(hconf);
let url = json.url;
if (json.encrypt == '1') {
url = unescape(url);
} else if (json.encrypt == '2') {
url = unescape(base64Decode(url));
}
if (/\\.(m3u8|mp4|m4a|mp3)/.test(url)) {
input = {
parse: 0,
jx: 0,
url: url,
};
} else {
input = url && url.startsWith('http') && tellIsJx(url) ? {parse:0,jx:1,url:url}:input;
}`;
// 默认嗅探播放
let def_lazy = `js:
input = { parse: 1, url: input, js: '' };`;
// 采集站播放
let cj_lazy = `js:
if (/\\.(m3u8|mp4)/.test(input)) {
input = { parse: 0, url: input };
} else {
if (rule.parse_url.startsWith('json:')) {
let purl = rule.parse_url.replace('json:', '') + input;
let html = request(purl);
let json = JSON.parse(html);
if (json.url) {
input = { parse: 0, url: json.url };
}
} else {
input = rule.parse_url + input;
}
}`;
function getMubans() {
const mubanDict = { // 模板字典
mx: {
title: '',
host: '',
url: '/vodshow/fyclass--------fypage---/',
searchUrl: '/vodsearch/**----------fypage---/',
class_parse: '.top_nav li;a&&Text;a&&href;.*/(.*?)/',
searchable: 2,
quickSearch: 0,
filterable: 0,
headers: {
'User-Agent': 'MOBILE_UA',
},
play_parse: true,
lazy: common_lazy,
limit: 6,
double: true,
推荐: '.cbox_list;*;*;*;*;*',
一级: 'ul.vodlist li;a&&title;a&&data-original;.pic_text&&Text;a&&href',
二级: {
title: 'h2&&Text;.content_detail:eq(1)&&li&&a:eq(2)&&Text',
img: '.vodlist_thumb&&data-original',
desc: '.content_detail:eq(1)&&li:eq(1)&&Text;.content_detail:eq(1)&&li&&a&&Text;.content_detail:eq(1)&&li&&a:eq(1)&&Text;.content_detail:eq(1)&&li:eq(2)&&Text;.content_detail:eq(1)&&li:eq(3)&&Text',
content: '.content_desc&&span&&Text',
tabs: '.play_source_tab&&a',
lists: '.content_playlist:eq(#id) li',
},
搜索: '*',
},
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(0):lt(10);a&&Text;a&&href;/(\\d+)',
play_parse: true,
lazy: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: '.tab-list.active;a.module-poster-item.module-item;.module-poster-item-title&&Text;.lazyload&&data-original;.module-item-note&&Text;a&&href',
一级: 'body a.module-poster-item.module-item;a&&title;.lazyload&&data-original;.module-item-note&&Text;a&&href',
二级: {
title: 'h1&&Text;.module-info-tag-link:eq(-1)&&Text',
img: '.lazyload&&data-original||data-src||src',
desc: '.module-info-item:eq(-2)&&Text;.module-info-tag-link&&Text;.module-info-tag-link:eq(1)&&Text;.module-info-item:eq(2)&&Text;.module-info-item:eq(1)&&Text',
content: '.module-info-introduction&&Text',
tabs: '.module-tab-item',
lists: '.module-play-list:eq(#id) a',
tab_text: 'div--small&&Text',
},
搜索: '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: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: '.module-list;.module-items&&.module-item;a&&title;img&&data-src;.module-item-text&&Text;a&&href',
一级: '.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(3)&&Text;.tag-link:eq(2)&&Text;.tag-link:eq(1)&&Text;.video-info-items:eq(1)&&Text;.video-info-items:eq(0)&&Text',
content: '.vod_content&&Text',
tabs: '.module-tab-item',
lists: '.module-player-list:eq(#id)&&.scroll-content&&a',
tab_text: 'div--small&&Text',
},
搜索: '.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(7);a&&Text;a&&href;/(\\d+).html',
play_parse: true,
lazy: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: 'ul.myui-vodlist.clearfix;li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
一级: '.myui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
二级: {
title: '.myui-content__detail .title--span&&Text;.myui-content__detail p.data:eq(3)&&Text',
img: '.myui-content__thumb .lazyload&&data-original',
desc: '.myui-content__detail p.otherbox&&Text;.year&&Text;.myui-content__detail p.data:eq(4)&&Text;.myui-content__detail p.data:eq(2)&&Text;.myui-content__detail p.data:eq(0)&&Text',
content: '.content&&Text',
tabs: '.myui-panel__head&&li',
// tabs: '.nav-tabs&&li',
lists: '.myui-content__list:eq(#id) li',
},
搜索: '#searchList li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href;.detail&&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;.*/(.*?).html',
play_parse: true,
lazy: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: 'ul.stui-vodlist.clearfix;li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href',
一级: '.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)&&a&&Text',
title1: '.stui-content__detail .title&&Text;.stui-content__detail&&p&&Text',
img: '.stui-content__thumb .lazyload&&data-original',
desc: '.stui-content__detail p&&Text;.stui-content__detail&&p:eq(-2)&&a:eq(2)&&Text;.stui-content__detail&&p:eq(-2)&&a:eq(1)&&Text;.stui-content__detail p:eq(2)&&Text;.stui-content__detail p:eq(1)&&Text',
desc1: '.stui-content__detail p:eq(4)&&Text;;;.stui-content__detail p:eq(1)&&Text',
content: '.detail&&Text',
tabs: '.stui-pannel__head h3',
tabs1: '.stui-vodlist__head h3',
lists: '.stui-content__playlist:eq(#id) li',
},
搜索: 'ul.stui-vodlist__media,ul.stui-vodlist,#searchList li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href;.detail&&Text',
},
默认: {
title: '',
host: '',
url: '',
searchUrl: '',
searchable: 2,
quickSearch: 0,
filterable: 0,
filter: '',
filter_url: '',
filter_def: {},
headers: {
'User-Agent': 'MOBILE_UA',
},
timeout: 5000,
class_parse: '#side-menu li;a&&Text;a&&href;/(.*?)\.html',
cate_exclude: '',
play_parse: true,
lazy: def_lazy,
double: true,
推荐: '列表1;列表2;标题;图片;描述;链接;详情',
一级: '列表;标题;图片;描述;链接;详情',
二级: {
title: 'vod_name;vod_type',
img: '图片链接',
desc: '主要信息;年代;地区;演员;导演',
content: '简介',
tabs: '',
lists: 'xx:eq(#id)&&a',
tab_text: 'body&&Text',
list_text: 'body&&Text',
list_url: 'a&&href',
},
搜索: '列表;标题;图片;描述;链接;详情',
},
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;a&&Text;a&&href;.*/(.*?).html',
play_parse: true,
lazy: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: 'ul.fed-list-info.fed-part-rows;li;a.fed-list-title&&Text;a&&data-original;.fed-list-remarks&&Text;a&&href',
一级: '.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: common_lazy,
double: true,
推荐: '.hl-vod-list;li;a&&title;a&&data-original;.remarks&&Text;a&&href',
一级: '.hl-vod-list&&.hl-list-item;a&&title;a&&data-original;.remarks&&Text;a&&href',
二级: {
title: '.hl-dc-title&&Text;.hl-dc-content&&li:eq(6)&&Text',
img: '.hl-lazy&&data-original',
desc: '.hl-dc-content&&li:eq(10)&&Text;.hl-dc-content&&li:eq(4)&&Text;.hl-dc-content&&li:eq(5)&&Text;.hl-dc-content&&li:eq(2)&&Text;.hl-dc-content&&li:eq(3)&&Text',
content: '.hl-content-text&&Text',
tabs: '.hl-tabs&&a',
tab_text: 'a--span&&Text',
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: common_lazy,
double: true,
推荐: '.list-a.size;li;a&&title;.lazy&&data-original;.bt&&Text;a&&href',
一级: '.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: common_lazy,
limit: 6,
double: true, // 推荐内容是否双层定位
推荐: '.indexShowBox;ul&&li;a&&title;img&&data-src;.s1&&Text;a&&href',
一级: '.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=**&limit=50',
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',
play_parse: true,
lazy: common_lazy,
limit: 6,
推荐: '.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(2)--strong&&Text',
img: '.detail-pic&&data-original',
desc: '.slide-info-remarks&&Text;.slide-info-remarks:eq(1)&&Text;.slide-info-remarks:eq(2)&&Text;.slide-info:eq(1)--strong&&Text;.info-parameter&&ul&&li:eq(3)&&Text',
content: '#height_limit&&Text',
tabs: '.anthology.wow.fadeInUp.animated&&.swiper-wrapper&&a',
tab_text: 'a--span&&Text',
lists: '.anthology-list-box:eq(#id) li',
},
搜索: 'json:list;name;pic;;id',
},
采集1: {
title: '',
host: '',
homeTid: '13',
homeUrl: '/api.php/provide/vod/?ac=detail&t={{rule.homeTid}}',
detailUrl: '/api.php/provide/vod/?ac=detail&ids=fyid',
searchUrl: '/api.php/provide/vod/?wd=**&pg=fypage',
url: '/api.php/provide/vod/?ac=detail&pg=fypage&t=fyclass',
headers: {
'User-Agent': 'MOBILE_UA'
},
timeout: 5000, // class_name: '电影&电视剧&综艺&动漫',
// class_url: '1&2&3&4',
// class_parse:'js:let html=request(input);input=JSON.parse(html).class;',
class_parse: 'json:class;',
limit: 20,
multi: 1,
searchable: 2, //是否启用全局搜索,
quickSearch: 1, //是否启用快速搜索,
filterable: 0, //是否启用分类筛选,
play_parse: true,
parse_url: '',
lazy: cj_lazy,
推荐: '*',
一级: 'json:list;vod_name;vod_pic;vod_remarks;vod_id;vod_play_from',
二级: `js:
let html=request(input);
html=JSON.parse(html);
let data=html.list;
VOD=data[0];`,
搜索: '*',
},
};
return JSON.parse(JSON.stringify(mubanDict));
}
var mubanDict = getMubans();
var muban = getMubans();
export default {
muban,
getMubans
};
-107
View File
@@ -1,107 +0,0 @@
let host = 'https://www.ylys.tv';
let headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": host + "/"
};
async function init(cfg) {}
/**
* 通用解析:不做过滤,不做干扰
*/
function getList(html) {
let videos = [];
let items = pdfa(html, ".module-item,.module-card-item");
items.forEach(it => {
let idMatch = it.match(/detail\/(\d+)/);
let nameMatch = it.match(/title="(.*?)"/) || it.match(/<strong>(.*?)<\/strong>/);
let picMatch = it.match(/data-original="(.*?)"/) || it.match(/src="(.*?)"/);
if (idMatch && nameMatch) {
let pic = picMatch ? (picMatch[1] || picMatch[2]) : "";
videos.push({
"vod_id": idMatch[1],
"vod_name": nameMatch[1].replace(/<.*?>/g, ""),
"vod_pic": pic.startsWith('/') ? host + pic : pic,
"vod_remarks": (it.match(/module-item-note">(.*?)<\/div>/) || ["",""])[1].replace(/<.*?>/g, "")
});
}
});
return videos;
}
async function home(filter) {
return JSON.stringify({
"class": [
{"type_id":"1","type_name":"电影"},
{"type_id":"2","type_name":"剧集"},
{"type_id":"3","type_name":"综艺"},
{"type_id":"4","type_name":"动漫"}
],
"filters": {
"1":[{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"动作片","v":"6"},{"n":"喜剧片","v":"7"},{"n":"爱情片","v":"8"},{"n":"科幻片","v":"9"},{"n":"恐怖片","v":"11"}]}],
"2":[{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"国产剧","v":"13"},{"n":"港台剧","v":"14"},{"n":"日剧","v":"15"},{"n":"韩剧","v":"33"},{"n":"欧美剧","v":"16"}]}],
"3":[{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"内地综艺","v":"27"},{"n":"港台综艺","v":"28"},{"n":"日本综艺","v":"29"},{"n":"韩国综艺","v":"36"}]}],
"4":[{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"国产动漫","v":"31"},{"n":"日本动漫","v":"32"},{"n":"欧美动漫","v":"42"},{"n":"其他动漫","v":"43"}]}]
}
});
}
async function homeVod() {
let resp = await req(host, { headers: headers });
return JSON.stringify({ list: getList(resp.content) });
}
async function category(tid, pg, filter, extend) {
let p = pg || 1;
let targetId = (extend && extend.class) ? extend.class : tid;
let url = host + "/vodtype/" + targetId + "/" + (parseInt(p) > 1 ? "page/" + p + "/" : "");
let resp = await req(url, { headers: headers });
return JSON.stringify({
"list": getList(resp.content),
"page": parseInt(p)
});
}
async function detail(id) {
let url = host + '/voddetail/' + id + '/';
let resp = await req(url, { headers: headers });
let html = resp.content;
let playFrom = pdfa(html, ".module-tab-item").map(it => (it.match(/<span>(.*?)<\/span>/) || ["","线路"])[1]).join('$$$');
let playUrl = pdfa(html, ".module-play-list-content").map(list =>
pdfa(list, "a").map(a => {
let n = (a.match(/<span>(.*?)<\/span>/) || ["","播放"])[1];
let v = a.match(/href="\/play\/(.*?)\/"/);
return n + '$' + (v ? v[1] : "");
}).join('#')
).join('$$$');
return JSON.stringify({
list: [{
'vod_id': id,
'vod_name': (html.match(/<h1>(.*?)<\/h1>/) || ["", ""])[1],
'vod_pic': (html.match(/data-original="(.*?)"/) || ["", ""])[1],
'vod_content': (html.match(/introduction-content">.*?<p>(.*?)<\/p>/s) || ["", ""])[1].replace(/<.*?>/g, ""),
'vod_play_from': playFrom,
'vod_play_url': playUrl
}]
});
}
async function search(wd, quick, pg) {
let p = pg || 1;
let url = host + "/vodsearch/" + encodeURIComponent(wd) + "-------------/" + (parseInt(p) > 1 ? "page/" + p + "/" : "");
let resp = await req(url, { headers: headers });
return JSON.stringify({ list: getList(resp.content) });
}
async function play(flag, id, flags) {
let url = host + "/play/" + id + "/";
let resp = await req(url, { headers: headers });
let m3u8 = resp.content.match(/"url":"([^"]+\.m3u8)"/);
if (m3u8) return JSON.stringify({ parse: 0, url: m3u8[1].replace(/\\/g, ""), header: headers });
return JSON.stringify({ parse: 1, url: url, header: headers });
}
export default { init, home, homeVod, category, detail, search, play };
-150
View File
@@ -1,150 +0,0 @@
const host = 'https://www.haigui.tv';
const headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Referer": host + "/"
};
async function init(cfg) {}
const m = (s, r, i = 1) => (s.match(r) || [])[i] || "";
const fixPic = p => p && p.startsWith('/') ? host + p : p;
function getList(html) {
return pdfa(html, ".module-item").map(it => {
let id = m(it, /href="\/video\/(.*?)\/"/);
let name = m(it, /title="(.*?)"/);
if (!id || !name) return null;
return {
vod_id: id,
vod_name: name,
vod_pic: fixPic(m(it, /data-original="(.*?)"/) || m(it, /src="(.*?)"/)),
vod_remarks: m(it, /module-item-note">(.*?)<\/div>/).replace(/<.*?>/g, "")
};
}).filter(Boolean);
}
async function home(filter) {
const classes = [
["dianying","电影"],["dianshiju","电视剧"],["zongyi","综艺"],
["dongman","动漫"],["jilupian","纪录片"],["duanju","短剧"]
].map(([id,name]) => ({type_id:id,type_name:name}));
const dict = {
area: ["中国大陆","中国香港","中国台湾","美国","韩国","日本","泰国"],
year: ["2025","2024","2023","2022","2021","2020"],
lang: ["国语","英语","粤语","韩语","日语"]
};
const filters = {};
classes.forEach(c => {
filters[c.type_id] = [
{ key:"class", name:"类型", value:getSubClasses(c.type_id) },
...Object.keys(dict).map(k => ({
key:k,
name:{area:"地区",year:"年份",lang:"语言"}[k],
value:[{n:"全部",v:""}].concat(dict[k].map(v=>({n:v,v})))
}))
];
});
return JSON.stringify({ class: classes, filters });
}
function getSubClasses(tid) {
const map = {
dianying: [
["dongzuopian","动作片"],["xijupian","喜剧片"],
["aiqingpian","爱情片"],["kehuanpian","科幻片"],["kongbupian","恐怖片"]
],
dianshiju: [
["guochanju","国产剧"],["gangtaiju","港台剧"],
["rihanju","日韩剧"],["oumeiju","欧美剧"]
]
};
return [{n:"全部",v:""}].concat((map[tid]||[]).map(([v,n])=>({n,v})));
}
async function homeVod() {
const r = await req(host,{headers});
return JSON.stringify({ list:getList(r.content) });
}
async function category(tid, pg, filter, extend={}) {
let p = pg || 1;
let id = extend.class || tid;
let url = `${host}/filter/${id}`;
["area","lang","year"].forEach(k=>{
if (extend[k]) url += `/${k}/${encodeURIComponent(extend[k])}`;
});
url += `/page/${p}/`;
const r = await req(url,{headers});
return JSON.stringify({ page:p, list:getList(r.content) });
}
async function detail(id) {
const r = await req(`${host}/video/${id}/`,{headers});
const h = r.content;
const playFrom = pdfa(h,".module-tab-item")
.map(it=>m(it,/<span>(.*?)<\/span>/)||"播放源")
.join("$$$");
const playUrl = pdfa(h,".module-player-list").map(l =>
pdfa(l,".module-blocklist a").map(it=>{
let pid = m(it,/href=\"\/play\/(.*?)\/\"/);
if (!pid) return null;
return `${m(it,/<span>(.*?)<\/span>/)||"正片"}$${pid}`;
}).filter(Boolean).join("#")
).join("$$$");
return JSON.stringify({
list:[{
vod_id:id,
vod_name:m(h,/page-title\">(.*?)<\/h1>/),
vod_pic:fixPic(m(h,/video-cover.*?data-src=\"(.*?)\"/)||m(h,/video-cover.*?src=\"(.*?)\"/)),
type_name:(
m(h,/tag-link[^>]*>[\s\S]*?icon-cate-[^<]*<\/i>\s*([^<\n]+)/) ||
m(h,/icon-cate-[^<]*<\/i>\s*([^<\n]+)/)
).trim(),
vod_year:m(h,/year\/(\d+)\//),
vod_area:m(h,/area\/.*?\/ \">(.*?)\t/s).trim(),
vod_director:m(h,/导演:<\/span>.*?<div.*?>(.*?)<\/div>/s).replace(/<.*?>|\//g,"").trim(),
vod_actor:m(h,/主演:<\/span>.*?<div.*?>(.*?)<\/div>/s).replace(/<.*?>|\//g,"").trim(),
vod_remarks:m(h,/备注:<\/span>.*?<div.*?>(.*?)<\/div>/),
vod_content:m(h,/vod_content.*?<span>(.*?)<\/span>/s)||"暂无简介",
vod_play_from:playFrom,
vod_play_url:playUrl
}]
});
}
async function search(wd, quick, pg=1) {
let url = `${host}/search/${encodeURIComponent(wd)}/${pg>1?`page/${pg}/`:""}`;
const r = await req(url,{headers});
const h = r.content;
const items = pdfa(h,".module-search-item") || pdfa(h,".module-item");
const list = items.map(it=>{
let id = m(it,/\/video\/(.*?)\//);
let name = m(it,/title=\"(.*?)\"/) || m(it,/alt=\"(.*?)\"/);
if (!id || !name) return null;
return {
vod_id:id,
vod_name:name,
vod_pic:fixPic(m(it,/data-src=\"(.*?)\"/)||m(it,/data-original=\"(.*?)\"/)||m(it,/src=\"(.*?)\"/)),
vod_remarks:m(it,/module-item-note\">(.*?)<\/div>/)||m(it,/video-serial\">(.*?)<\/span>/)
};
}).filter(Boolean);
return JSON.stringify({ page:pg, list });
}
async function play(flag, id, flags) {
const r = await req(`${host}/play/${id}/`,{headers});
let u = m(r.content,/"url":"([^"]+\.m3u8[^"]*)"/);
if (u) return JSON.stringify({ parse:0, url:u.replace(/\\/g,""), header:headers });
return JSON.stringify({ parse:1, url:`${host}/play/${id}/`, header:headers });
}
export default { init, home, homeVod, category, detail, search, play };
-360
View File
@@ -1,360 +0,0 @@
/*
title: '爱看机器人', author: '小可乐/v6.1.2'
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
"ext": {
"host": "xxxx", //站点网址
"timeout": 6000, //请求超时,单位毫秒
"tabsSet": "线路2&线路1" //指定线路和顺序
"tabsDeal": "量子&非凡@天堂>360#极速<新浪@优质>>优质无广&暴风>>暴风无广" //线路处理,优先级低于tabsSet,功能依次为"删除@排序@改名",功能用@分隔,优先级从高到低,排序中的#号表示反向排序从此开始,不理解自己试试就明白了
}
*/
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36';
const DefHeader = {'User-Agent': MOBILE_UA};
var HOST;
var KParams = {
headers: {'User-Agent': MOBILE_UA},
timeout: 8000,
};
async function init(cfg) {
try {
HOST = (cfg.ext?.host?.trim() || 'https://v.aikanbot.com').replace(/\/$/, '');
KParams.headers['Referer'] = HOST;
let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10);
if (parseTimeout > 0) {KParams.timeout = parseTimeout;}
KParams.tabsSet = cfg.ext?.tabsSet?.trim() || '';
KParams.tabsDeal = cfg.ext?.tabsDeal?.trim() || '';
} catch (e) {
console.error('初始化参数失败:', e.message);
}
}
async function home(filter) {
try {
let kclassName = '电影$movie&剧集$tv&榜单$billboard';
let classes = kclassName.split('&').map(it => {
let [cName, cId] = it.split('$');
return {type_name: cName, type_id: cId};
});
let filters = {
"movie": [
{"key": "class","name": "剧情","value": [{"n": "热门","v": "热门"}, {"n": "最新","v": "最新"}, {"n": "经典","v": "经典"}, {"n": "豆瓣高分","v": "豆瓣高分"}, {"n": "冷门佳片","v": "冷门佳片"}, {"n": "华语","v": "华语"}, {"n": "欧美","v": "欧美"}, {"n": "韩国","v": "韩国"}, {"n": "日本","v": "日本"}, {"n": "动作","v": "动作"}, {"n": "喜剧","v": "喜剧"}, {"n": "爱情","v": "爱情"}, {"n": "科幻","v": "科幻"}, {"n": "悬疑","v": "悬疑"}, {"n": "恐怖","v": "恐怖"}, {"n": "成长","v": "成长"}, {"n": "豆瓣top250","v": "豆瓣top250"}]}
],
"tv": [
{"key": "class","name": "剧情","value": [{"n": "热门","v": "热门"}, {"n": "美剧","v": "美剧"}, {"n": "英剧","v": "英剧"}, {"n": "韩剧","v": "韩剧"}, {"n": "日剧","v": "日剧"}, {"n": "国产剧","v": "国产剧"}, {"n": "港剧","v": "港剧"}, {"n": "日本动画","v": "日本动画"}, {"n": "综艺","v": "综艺"}, {"n": "纪录片","v": "纪录片"}]}
]
};
return JSON.stringify({class: classes, filters: filters});
} catch (e) {
console.error('获取分类失败:', e.message);
return JSON.stringify({class: [], filters: {}});
}
}
async function homeVod() {
try {
let resHtml = await request(HOST);
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS});
} catch (e) {
console.error('推荐页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function category(tid, pg, filter, extend) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let fl = extend || {};
let suffix = pg === 1 ? '' : `-p-${pg}`;
let cateUrl = tid === 'billboard' ? `${HOST}/billboard.html` : `${HOST}/hot/index-${tid}-${fl.class || '热门'}${suffix}.html`;
let resHtml = await request(cateUrl);
let VODS = getVodList(resHtml);
let limit = VODS.length;
let hasMore = cutStr(resHtml, 'page-more">', '</div>').includes('下一页');
let pagecount = hasMore ? pg + 1 : pg;
return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: limit, total: limit*pagecount});
} catch (e) {
console.error('类别页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
async function search(wd, quick, pg) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let suffix = pg === 1 ? '' : `&p=${pg}`;
let searchUrl = `${HOST}/search?q=${wd}${suffix}`;
let resHtml = await request(searchUrl);
let VODS = getVodList(resHtml, true);
return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300});
} catch (e) {
console.error('搜索页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
function getVodList(khtml, sch = false) {
try {
if (!khtml) {throw new Error('源码为空');}
let kvods = [];
let listArr = sch ? cutStr(khtml, 'media">', '</h5>', '', false, 0, true) : cutStr(khtml, '<a', '/a>', '', false, 0, true).filter(flt => flt.includes('alt='));
let picProxy = 'https://img-p.aikanbot.com/proxy?url=';
for (let it of listArr) {
let kname = sch ? cutStr(it, 'title-text">', '<', '名称') : cutStr(it, 'alt="', '"', '名称');
let kpic = `${picProxy}${cutStr(it, 'data-src="', '"', '图片')}`;
let kremarks = sch ? cutStr(it, '[', ']', '状态') : '无状态';
let kid = cutStr(it, 'href="', '"');
if (kid) {
kvods.push({
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
vod_id: `${kid}@${kname}@${kpic}@${kremarks}`
});
}
}
return kvods;
} catch (e) {
console.error(`生成视频列表失败:`, e.message);
return [];
}
}
async function detail(ids) {
try {
let [id, kname, kpic, kremarks] = ids.split('@');
let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id;
let resHtml = await request(detailUrl);
if (!resHtml) {throw new Error('源码为空');}
const tabName = {"dyttm3u8":"天堂","360zy":"360","iqym3u8":"爱奇艺","mtm3u8":"茅台","subm3u8":"速播","nnm3u8":"牛牛","okm3u8":"欧克","tym3u8":"TY","yym3u8":"歪歪","bfzym3u8":"暴风","1080zyk":"优质","kuaikan":"快看","lzm3u8":"量子","ffm3u8":"非凡","snm3u8":"索尼","qhm3u8":"奇虎","hym3u8":"虎牙","haiwaikan":"海外看","gsm3u8":"光速","zuidam3u8":"最大","bjm3u8":"八戒","wolong":"卧龙","xlm3u8":"新浪","yhm3u8":"樱花","tkm3u8":"天空","jsm3u8":"极速","wjm3u8":"无尽","sdm3u8":"闪电","kcm3u8":"快车","jinyingm3u8":"金鹰","fsm3u8":"飞速","tpm3u8":"淘片","lem3u8":"鱼乐","dbm3u8":"百度","tomm3u8":"番茄","ukm3u8":"优酷","ikm3u8":"爱坤","hnzym3u8":"红牛资源","hnm3u8":"红牛","68zy_m3u8":"六八","kdm3u8":"酷点","bdxm3u8":"北斗星","hhm3u8":"豪华","kbm3u8":"快播","mzm3u8":"MZ"};
let [kdirector='', kactors=''] = cutStr(resHtml, '<h3£>', '</h3>', '', true, -1).split('/');
let kid= cutStr(resHtml, 'current_id"£"', '"');
let eToken= cutStr(resHtml, 'e_token"£"', '"');
const getToken = (curtId, eToken) => {
if (!curtId || !eToken || !/^\d+$/.test(curtId)) {return '';}
let remainEToken = eToken;
let finalToken = curtId.slice(-4).split('').map(it => {
let startPos = (parseInt(it, 10) % 3) + 1;
let endPos = startPos + 8;
if (startPos >= remainEToken.length) {return '';}
let segment = remainEToken.substring(startPos, endPos);
remainEToken = remainEToken.substring(endPos);
return segment;
}).filter(Boolean).join('');
return finalToken;
};
let token = getToken(kid, eToken);
let detailUrl2 = `${HOST}/api/getResN?videoId=${kid}&mtype=2&token=${token}`;
let resObj = safeParseJSON(await request(detailUrl2));
let resList = resObj?.data?.list ?? [];
let [ktabs, kurls] = [[], []];
resList.forEach((item, idx) => {
let resData = safeParseJSON(item.resData.replace(/#{2,}/g, '#'))?.[0] ?? {};
let tab = resData?.flag || `线路${idx+1}`;
ktabs.push(tabName[tab] || tab);
kurls.push(resData?.url || 'noUrl');
});
ktabs = dealSameEle(ktabs);
if (KParams.tabsSet || KParams.tabsDeal) {
let ktus = ktabs.map((it, idx) => { return {type_name: it, type_value: kurls[idx]} });
if (KParams.tabsSet) {
ktus = ctSet(ktus, KParams.tabsSet);
}
if (KParams.tabsDeal) {
let [x = '', y = '', z = ''] = KParams.tabsDeal.split('@');
let tab_remove = ['','&'].includes(x.trim()) ? '' : x.trim();
let tab_order = ['','#'].includes(y.trim()) ? '' : y.trim();
let tab_rename = ['','&'].includes(z.trim()) ? '' : z.trim();
ktus = dorDeal(ktus, tab_remove, tab_order, tab_rename);
}
ktabs = ktus.map(it => it.type_name);
kurls = ktus.map(it => it.type_value);
}
let VOD = {
vod_id: kid,
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
type_name: '类型',
vod_year: cutStr(resHtml, '<h3£>', '</h3>', '1000', true, -3),
vod_area: cutStr(resHtml, '<h3£>', '</h3>', '地区', true, -2),
vod_lang: '语言',
vod_director: kdirector || '导演',
vod_actor: kactors || '主演',
vod_content: cutStr(resHtml, 'description" content="', '">', kname),
vod_play_from: ktabs.join('$$$'),
vod_play_url: kurls.join('$$$')
};
return JSON.stringify({list: [VOD]});
} catch (e) {
console.error('详情页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function play(flag, ids, flags) {
try {
let kp = /\.(m3u8|mp4|mkv)/.test(ids) ? 0 : 1;
return JSON.stringify({jx: 0, parse: kp, url: ids, header: DefHeader});
} catch (e) {
console.error('播放失败:', e.message);
return JSON.stringify({jx: 0, parse: 0, url: '', header: {}});
}
}
function dealSameEle(arr) {
try {
if (!Array.isArray(arr)) {throw new Error('输入参数非数组');}
const countMap = new Map();
let newArr = arr.map(item => {
let count = countMap.get(item) || 0;
let currentCount = count + 1;
countMap.set(item, currentCount);
return currentCount > 1 ? `${item}${currentCount}` : item;
});
return newArr;
} catch (e) {
return [];
}
}
function ctSet(kArr, setStr) {
try {
if (!Array.isArray(kArr) || kArr.length === 0 || typeof setStr !== 'string' || !setStr) { throw new Error('第一参数需为非空数组,第二参数需为非空字符串'); }
const set_arr = [...kArr];
const arrNames = setStr.split('&');
const filtered_arr = arrNames.map(item => set_arr.find(it => it.type_name === item)).filter(Boolean);
return filtered_arr.length? filtered_arr : [set_arr[0]];
} catch (e) {
console.error('ctSet 执行异常:', e.message);
return kArr;
}
}
function dorDeal(kArr, strRemove, strOrder, strRename) {
let dealed_arr = [...kArr];
if (strRemove) {
try {
let removeArr = strRemove.split('&');
const removeSet = new Set(removeArr);
let filtered_arr = dealed_arr.filter(it => !removeSet.has(it.type_name));
let retained_arr = filtered_arr.length ? filtered_arr : [dealed_arr[0]];
dealed_arr = retained_arr;
} catch (e) {
console.error('删除失败:', e.message);
}
}
if (strOrder) {
try {
let [a = '', b = ''] = strOrder.split('#', 2);
let arrA = a.split('>').filter(Boolean);
let arrB = b.split('<').filter(Boolean);
let uqArrB = arrB.filter(it => !arrA.includes(it));
let twMap = new Map();
arrA.forEach((item, idx) => {twMap.set(item, { weight: 1, index: idx }); });
uqArrB.forEach((item, idx) => {twMap.set(item, { weight: 3, index: idx }); });
dealed_arr.forEach((it, idx) => { if (!twMap.has(it.type_name)) {twMap.set(it.type_name, { weight: 2, index: idx });} });
let ordered_arr = [...dealed_arr].sort((a, b) => {
let { weight: ta = 2, index: idxA = 0 } = twMap.get(a.type_name) ?? {};
let { weight: tb = 2, index: idxB = 0 } = twMap.get(b.type_name) ?? {};
if (ta !== tb) {return ta - tb;}
return ta === 3 ? idxB - idxA : idxA - idxB;
});
dealed_arr = ordered_arr;
} catch (e) {
console.error('排序失败:', e.message);
}
}
if (strRename) {
try {
const objRename = strRename.split('&').reduce((obj, p) => {
let [k = '', v = ''] = p.split('>>', 2);
if (k + v) {obj[k] = v;}
return obj;
}, {});
let renamed_arr = dealed_arr.map(it => { return { ...it, type_name: objRename[it.type_name] || it.type_name } });
dealed_arr = renamed_arr;
} catch (e) {
console.error('改名失败:', e.message);
}
}
return dealed_arr;
}
function safeParseJSON(jStr){
try {return JSON.parse(jStr);} catch(e) {return null;}
}
function cutStr(str, prefix = '', suffix = '', defVal = '', clean = true, i = 0, all = false) {
try {
if (typeof str !== 'string') {throw new Error('被截取对象必须为字符串');}
const cleanStr = cs => String(cs).replace(/<[^>]*?>/g, ' ').replace(/(&nbsp;|[\u0020\u00A0\u3000\s])+/g, ' ').trim().replace(/\s+/g, ' ');
const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&');
let pre = esc(prefix).replace(/£/g, '[^]*?'), end = esc(suffix);
const regex = new RegExp(`${pre || '^'}([^]*?)${end || '$'}`, 'g');
const matchIter = str.matchAll(regex);
if (all) {
const matchArr = [...matchIter];
return matchArr.length ? matchArr.map(ela => ela[1] !== undefined ? (clean ? (cleanStr(ela[1]) || defVal) : ela[1]) : defVal ) : [defVal];
}
const idx = parseInt(i, 10);
if (isNaN(idx)) {throw new Error('序号必须为整数');}
let tgResult, matchIdx = 0;
if (idx >= 0) {
for (let elt of matchIter) {
if (matchIdx++ === idx) {tgResult = elt[1]; break;}
}
} else {
const matchArr = [...matchIter];
tgResult = matchArr.length ? matchArr[matchArr.length + idx]?.[1] : undefined;
}
return tgResult !== undefined ? (clean ? (cleanStr(tgResult) || defVal) : tgResult) : defVal;
} catch (e) {
console.error(`字符串截取错误:`, e.message);
return all ? ['cutErr'] : 'cutErr';
}
}
async function request(reqUrl, options = {}) {
try {
if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); }
if (typeof options !== 'object' || Array.isArray(options) || options === null) { throw new Error('options类型需为非null对象'); }
options.method = options.method?.toUpperCase() || 'GET';
if (['GET', 'HEAD'].includes(options.method)) {
delete options.body;
delete options.data;
delete options.postType;
}
let {headers, timeout, ...restOpts} = options;
const optObj = {
headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers,
timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout,
...restOpts
};
const res = await req(reqUrl, optObj);
if (options.withHeaders) {
const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {};
const resWithHeaders = { ...resHeaders, body: res?.content ?? '' };
return JSON.stringify(resWithHeaders);
}
return res?.content ?? '';
} catch (e) {
console.error(`${reqUrl}→请求失败:`, e.message);
return options?.withHeaders ? JSON.stringify({ body: '' }) : '';
}
}
export function __jsEvalReturn() {
return {
init,
home,
homeVod,
category,
search,
detail,
play,
proxy: null
};
}
-169
View File
@@ -1,169 +0,0 @@
import 'assets://js/lib/crypto-js.js';
const { HOSTS, KEY, USER_AGENT } = {
HOSTS: ["https://hnytxj.com","https://www.hkybqufgh.com","https://www.sizhengxt.com","https://www.sdzhgt.com","https://www.jiabaide.cn","https://m.9zhoukj.com","https://m.cqzuoer.com","https://www.hellosht52bwb.com"],
KEY: "cb808529bae6b6be45ecfab29a4889bc",
USER_AGENT: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Safari/537.36"
};
let currentHost = '';
const guid = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
const r = Math.random() * 16 | 0;
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
const md5 = s => CryptoJS.MD5(s).toString();
const sha1 = s => CryptoJS.SHA1(s).toString();
const toQueryString = obj => Object.keys(obj).filter(k => obj[k] != null && obj[k] !== '').map(k => `${k}=${obj[k]}`).join('&');
const getHeaders = (params = {}) => {
const t = Date.now().toString();
const sign = sha1(md5(toQueryString({ ...params, key: KEY, t })));
return {
'User-Agent': USER_AGENT,
'Accept': 'application/json, text/plain, */*',
'sign': sign,
't': t,
'deviceid': guid()
};
};
const normalizeFieldName = k => {
const l = k.toLowerCase();
if (l.startsWith('vod') && l.length > 3) return 'vod_' + l.slice(3);
if (l.startsWith('type') && l.length > 4) return 'type_' + l.slice(4);
return l;
};
const normalizeVodList = list => (list || []).map(item => {
const res = {};
for (const [k, v] of Object.entries(item || {})) if (v != null) res[normalizeFieldName(k)] = v;
return res;
});
async function reqSafe(url, options = {}) {
try {
const res = await req(url, options);
return JSON.parse(res.content);
} catch (e) {
return {};
}
}
async function init() {
currentHost = HOSTS[Math.floor(Math.random() * HOSTS.length)];
return true;
}
async function home() {
const [cRes, fRes] = await Promise.all([
reqSafe(`${currentHost}/api/mw-movie/anonymous/get/filer/type`, { headers: getHeaders() }),
reqSafe(`${currentHost}/api/mw-movie/anonymous/v1/get/filer/list`, { headers: getHeaders() })
]);
const classes = (cRes.data || []).map(k => ({ type_name: k.typeName, type_id: k.typeId.toString() }));
const fData = fRes.data || {};
const baseSort = [{ n: "最近更新", v: "2" }, { n: "人气高低", v: "3" }, { n: "评分高低", v: "4" }];
const filters = {};
for (const [tid, d] of Object.entries(fData)) {
const sortValues = tid === '1' ? baseSort.slice(1) : baseSort;
const arr = [
{ key: "type", name: "类型", value: (d.typeList || []).map(i => ({ n: i.itemText, v: i.itemValue })) },
{ key: "area", name: "地区", value: (d.districtList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
{ key: "year", name: "年份", value: (d.yearList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
{ key: "lang", name: "语言", value: (d.languageList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
{ key: "sort", name: "排序", value: sortValues }
];
if (d.plotList?.length) arr.splice(1, 0, { key: "v_class", name: "剧情", value: d.plotList.map(i => ({ n: i.itemText, v: i.itemText })) });
filters[tid] = arr;
}
return JSON.stringify({ class: classes, filters });
}
async function homeVod() {
const [r1, r2] = await Promise.all([
reqSafe(`${currentHost}/api/mw-movie/anonymous/v1/home/all/list`, { headers: getHeaders() }),
reqSafe(`${currentHost}/api/mw-movie/anonymous/home/hotSearch`, { headers: getHeaders() })
]);
let list = [];
const data1 = r1.data || {};
for (const k in data1) if (data1[k]?.list) list.push(...data1[k].list);
if (Array.isArray(r2.data)) list.push(...r2.data);
return JSON.stringify({ list: normalizeVodList(list) });
}
async function category(tid, pg, _, ext = {}) {
const params = {
area: ext.area || '',
filterStatus: "1",
lang: ext.lang || '',
pageNum: pg,
pageSize: "30",
sort: ext.sort || '1',
sortBy: "1",
type: ext.type || '',
type1: tid,
v_class: ext.v_class || '',
year: ext.year || ''
};
const url = `${currentHost}/api/mw-movie/anonymous/video/list?${toQueryString(params)}`;
const res = await reqSafe(url, { headers: getHeaders(params) });
const vodList = normalizeVodList(res.data?.list || []);
return JSON.stringify({
list: vodList,
page: +pg,
pagecount: 9999,
limit: 90,
total: 999999
});
}
async function detail(id) {
const res = await reqSafe(`${currentHost}/api/mw-movie/anonymous/video/detail?id=${id}`, {
headers: getHeaders({ id })
});
const vod = normalizeVodList([res.data])[0];
if (!vod) {
return JSON.stringify({ list: [{ vod_id: id, vod_name: '加载失败', vod_play_url: '' }] });
}
vod.vod_play_from = '金牌影院';
if (vod.episodelist?.length) {
const name = vod.episodelist.length > 1 ? vod.episodelist[0].name : vod.vod_name;
vod.vod_play_url = vod.episodelist.map(ep => `${name}$${id}@@${ep.nid}`).join('#');
delete vod.episodelist;
}
return JSON.stringify({ list: [vod] });
}
async function play(_, id) {
const [vid, nid] = id.split('@@');
const url = `${currentHost}/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id=${vid}&nid=${nid}`;
const res = await reqSafe(url, { headers: getHeaders({ clientType: '1', id: vid, nid: nid }) });
const urls = [];
for (const item of res.data?.list || []) {
urls.push(item.resolutionName, item.url);
}
return JSON.stringify({
parse: 0,
url: urls,
header: {
'User-Agent': USER_AGENT,
'sec-ch-ua-platform': '"Windows"',
'DNT': '1',
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
'sec-ch-ua-mobile': '?0',
'Origin': currentHost,
'Referer': currentHost + '/'
}
});
}
async function search(wd, _, pg = "1") {
const params = { keyword: wd, pageNum: pg, pageSize: "8", sourceCode: "1" };
const url = `${currentHost}/api/mw-movie/anonymous/video/searchByWord?${toQueryString(params)}`;
const res = await reqSafe(url, { headers: getHeaders(params) });
const list = normalizeVodList(res.data?.result?.list || []);
return JSON.stringify({ list, page: +pg });
}
export function __jsEvalReturn() {
return { init, home, homeVod, category, detail, play, proxy: null, search };
}
-115
View File
@@ -1,115 +0,0 @@
let host = 'https://www.guipian360.com';
let headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": host + "/"
};
const extractVideos = html => {
if (!html) return [];
return pdfa(html, '.m-movies .u-movie').map(it => {
const url = it.match(/href="([^"]+)"/)?.[1] || "";
const id = url.match(/\/(\d+)\.html/)?.[1];
let name = it.match(/title="([^"]+)"/)?.[1] || "";
name = name.split('/')[0].trim().replace(/.*《([^》]+)》.*/, "$1");
const pic = it.match(/src="([^"]+)"/)?.[1] || "";
const remarks = it.match(/class="zhuangtai"[^>]*>([^<]+)/)?.[1] || "";
return id && name ? {
vod_id: id,
vod_name: name,
vod_pic: pic.startsWith('/') ? host + pic : pic,
vod_remarks: remarks.trim()
} : null;
}).filter(Boolean);
};
const home = async () => {
const list = extractVideos((await req(host, { headers }))?.content || '');
return JSON.stringify({
class: [
{type_id:"1",type_name:"鬼片大全"},{type_id:"6",type_name:"大陆鬼片"},{type_id:"9",type_name:"港台鬼片"},
{type_id:"8",type_name:"林正英鬼片"},{type_id:"7",type_name:"日韩鬼片"},{type_id:"11",type_name:"欧美鬼片"},
{type_id:"10",type_name:"泰国鬼片"},{type_id:"3",type_name:"恐怖片"},{type_id:"2",type_name:"电视剧"},
{type_id:"12",type_name:"国产剧"},{type_id:"20",type_name:"港台剧"},{type_id:"13",type_name:"美剧"},
{type_id:"14",type_name:"韩剧"},{type_id:"15",type_name:"日剧"},{type_id:"16",type_name:"泰剧"},
{type_id:"22",type_name:"其它剧"},{type_id:"4",type_name:"动漫"}
],
filters: {},
list
});
};
const homeVod = async () => {
const list = extractVideos((await req(host, { headers }))?.content || '');
return JSON.stringify({ list });
};
const category = async (tid, pg, _, extend) => {
const url = pg > 1 ? `${host}/list/${tid}_${pg}.html` : `${host}/list/${tid}.html`;
const html = (await req(url, { headers }))?.content || '';
const list = extractVideos(html);
const m = html.match(/href="\/list\/\d+_(\d+)\.html"[^>]*>\.\.(\d+)<\/a>/);
return JSON.stringify({ list, page: +pg, pagecount: m ? +m[1] : 999, limit: 20 });
};
const detail = async id => {
const html = (await req(`${host}/nv/${id}.html`, { headers }))?.content || '';
if (!html) return JSON.stringify({ list: [] });
const tabs = pdfa(html, '#tv_tab li a').map(a => (a.match(/>([^<]+)/)?.[1] || "线路").trim());
const urls = pdfa(html, '#tv_tab .list').map(list =>
pdfa(list, 'ul.abc li a').map(a => {
const name = (a.match(/>([^<]+)/)?.[1] || "播放").trim();
const vid = (a.match(/href="\/play\/(.*?)\.html"/)?.[1] || "");
return `${name}$${vid}`;
}).join('#')
);
if (!tabs.length || !urls.length) return JSON.stringify({ list: [] });
let vod_name = (html.match(/<h1>(.*?)<\/h1>/)?.[1] || "").split('/')[0].trim().replace(/.*《([^》]+)】?.*/, "$1");
const m = s => (html.match(s) || ["", ""])[1].trim();
const vod_pic = m(/<img[^>]+src="([^"]+)"[^>]*class="lazy"/);
const vod_content = (html.match(/<p class="jianjie-p"[^>]*>([\s\S]*?)<\/p>/)?.[1] || "").replace(/<.*?>/g, "").trim() || "暂无简介";
return JSON.stringify({
list: [{
vod_id: id,
vod_name,
vod_pic: vod_pic.startsWith('/') ? host + vod_pic : vod_pic,
vod_content,
vod_director: m(/<li class="hidden-xs"><span>导演:<\/span>(.*?)<\/li>/),
vod_actor: m(/<li class="hidden-xs"><span>主演:<\/span>(.*?)<\/li>/),
vod_year: m(/<strong>(\d{4})年<\/strong>/),
vod_area: m(/地区:<\/span><a[^>]*>(.*?)<\/a>/),
vod_lang: m(/语言:<\/span>(.*?)<\/li>/),
vod_play_from: tabs.join('$$$'),
vod_play_url: urls.join('$$$')
}]
});
};
const search = async (wd, _, pg = 1) => {
const url = `${host}/vodsearch/${encodeURIComponent(wd)}----------${pg}---.html`;
const list = extractVideos((await req(url, { headers }))?.content || '');
return JSON.stringify({ list });
};
const play = async (_, id) => {
const html = (await req(`${host}/play/${id}.html`, { headers }))?.content || '';
const m3u8 = html.match(/var now="([^"]+)";/);
return JSON.stringify({
parse: m3u8 ? 0 : 1,
url: m3u8 ? m3u8[1] : `${host}/play/${id}.html`,
header: headers
});
};
export default {
init: async () => {},
home,
homeVod,
category,
detail,
search,
play
};