上传文件至「js」

This commit is contained in:
2026-08-15 13:59:13 +02:00
orang tua e04a1b0333
melakukan b486fe1c1b
5 mengubah file dengan 1647 tambahan dan 0 penghapusan
+69
Melihat File
File diff suppressed because one or more lines are too long
+434
Melihat File
@@ -0,0 +1,434 @@
/*
@header({
searchable: 1,
filterable: 1,
quickSearch: 0,
title: '荐片',
lang: 'cat'
})
*/
let siteName = '荐片', siteKey = '', siteType = 0;
let host = 'https://api.ztcgi.com';
let imghost = '';
let maxPages = 5;
let config = {};
let title_remove = ['名称排除', '广告', '破解', '群'];
let line_remove = ['线路排除', '广告', '666', 'mymv'];
let line_order = ['线路排序', '蓝光', 'ft', '官', 'ace', '1080p', 'dytt'];
let cate_remove = ['分类排除', '推荐', '首页'];
let rule = {
homeCategory: '/api/v2/settings/homeCategory',
resourceDomain: '/api/v2/settings/resourceDomainConfig',
slideList: '/api/slide/list',
dyTag: '/api/dyTag/tpl2_data',
crumbList: '/api/crumb/list',
detail: '/api/video/detailv2',
search: '/api/v2/search/videoV2'
};
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36'
};
function safeJSONParse(str, defaultValue = {}) {
if (!str || typeof str === 'object') return str || defaultValue;
try {
return JSON.parse(str);
} catch {
return defaultValue;
}
}
async function request(url, options = {}) {
const reqHeaders = { ...headers, ...options.headers };
let postType = reqHeaders['Content-Type']?.includes('json') ? 'json' :
reqHeaders['Content-Type']?.includes('form') ? 'form' : '';
try {
const response = await req(url, {
method: options.method || 'GET',
headers: reqHeaders,
data: options.data,
postType: postType,
timeout: options.timeout || 15000
});
return response?.content || response?.data || response;
} catch {
return null;
}
}
async function init(cfg) {
siteName = cfg.skey?.split('_')[1] || cfg.skey || '荐片';
siteKey = cfg.skey;
siteType = cfg.stype;
let ext = cfg.ext !== undefined ? cfg.ext : cfg;
if (typeof ext === 'string' && ext.includes('$')) {
const [url, order] = ext.split('$');
const response = await req(url, { headers, timeout: 10000 });
if (response && response.content) {
config = safeJSONParse(response.content)[order] || {};
host = config.host || config.hosturl || config.url || config.site;
}
} else if (ext && typeof ext === 'object') {
config = ext;
host = config.host || config.hosturl || config.url || config.site;
}
if (!host) {
host = 'https://api.ztcgi.com';
}
if (config.title_remove !== undefined) title_remove = Array.isArray(config.title_remove) ? config.title_remove : title_remove;
if (config.line_remove !== undefined) line_remove = Array.isArray(config.line_remove) ? config.line_remove : line_remove;
if (config.line_order !== undefined) line_order = Array.isArray(config.line_order) ? config.line_order : line_order;
if (config.cate_remove !== undefined) cate_remove = Array.isArray(config.cate_remove) ? config.cate_remove : cate_remove;
try {
let res = await req(`${host}${rule.resourceDomain}`, { headers, timeout: 10000 });
if (res && res.content) {
let configData = safeJSONParse(res.content);
if (configData.code === 1 && configData.data && configData.data.imgDomain) {
const domainList = configData.data.imgDomain.split(',');
imghost = `https://${domainList[Math.floor(Math.random() * domainList.length)].trim()}`;
}
}
} catch (e) {
imghost = 'https://img.jgsfnl.com';
}
}
async function home(filter) {
let html = await request(`${host}${rule.homeCategory}`);
if (!html) {
return JSON.stringify({ class: [], filters: {} });
}
let parsed = safeJSONParse(html);
let res = parsed.data;
if (!res || !Array.isArray(res)) {
return JSON.stringify({ class: [], filters: {} });
}
let classes = [];
res.forEach(item => {
if (item && item.id && item.name) {
classes.push({ type_id: item.id.toString(), type_name: item.name });
}
});
const commonFilter = [{
"key": "cateId", "name": "分类",
"value": [{"v": "", "n": "全部"}, {"v": "1", "n": "剧情"}, {"v": "2", "n": "爱情"}, {"v": "3", "n": "动画"}, {"v": "4", "n": "喜剧"}, {"v": "5", "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": "18", "n": "惊悚"}, {"v": "20", "n": "短片"}, {"v": "21", "n": "历史"}, {"v": "22", "n": "音乐"}, {"v": "23", "n": "西部"}, {"v": "24", "n": "武侠"}, {"v": "25", "n": "恐怖"}]
}, {
"key": "area", "name": "地区",
"value": [{"v": "", "n": "全部"}, {"v": "1", "n": "国产"}, {"v": "3", "n": "中国香港"}, {"v": "6", "n": "中国台湾"}, {"v": "5", "n": "美国"}, {"v": "18", "n": "韩国"}, {"v": "2", "n": "日本"}]
}, {
"key": "year", "name": "年代",
"value": [{"v": "", "n": "全部"}, {"v": "162", "n": "2026"}, {"v": "107", "n": "2025"}, {"v": "119", "n": "2024"}, {"v": "153", "n": "2023"}, {"v": "101", "n": "2022"}, {"v": "118", "n": "2021"}, {"v": "16", "n": "2020"}, {"v": "7", "n": "2019"}, {"v": "2", "n": "2018"}, {"v": "3", "n": "2017"}, {"v": "22", "n": "2016"}, {"v": "2015", "n": "2015以前"}]
}, {
"key": "sort", "name": "排序",
"value": [{"v": "update", "n": "最新"}, {"v": "hot", "n": "最热"}, {"v": "rating", "n": "评分"}]
}];
let filterObj = {};
classes.forEach(item => {
if (item.type_id !== '88' && item.type_id !== '99') {
filterObj[item.type_id] = commonFilter;
}
});
let i = 0;
while (i < classes.length) {
const isBad = cate_remove.some(word => new RegExp(word, 'i').test(classes[i].type_name));
if (isBad) {
classes.splice(i, 1);
} else {
i++;
}
}
return JSON.stringify({ class: classes, filters: filterObj });
}
async function homeVod() {
let html = await request(`${host}${rule.slideList}?pos_id=88`);
if (!html) {
return JSON.stringify({ list: [] });
}
let parsed = safeJSONParse(html);
let res = parsed.data;
if (!res || !Array.isArray(res)) {
return JSON.stringify({ list: [] });
}
let videos = [];
res.forEach(item => {
if (item && item.jump_id) {
videos.push({
vod_id: item.jump_id,
vod_name: item.title || '未知标题',
vod_pic: imghost ? `${imghost}${item.thumbnail || ''}` : (item.thumbnail || ''),
vod_remarks: "",
});
}
});
let filteredVideos = [];
videos.forEach(item => {
const title = item.vod_name;
const isBadTitle = title_remove.some(word => new RegExp(word, 'i').test(title));
if (!isBadTitle) {
filteredVideos.push(item);
}
});
return JSON.stringify({ list: filteredVideos });
}
async function DyTag(id, pg) {
let url = `${host}${rule.dyTag}?id=${id}&page=${pg}`;
let html = await request(url);
if (!html) return [];
let parsed = safeJSONParse(html);
let res = parsed.data;
if (!res || !Array.isArray(res)) return [];
let videos = [];
res.forEach(item => {
if (item) {
videos.push({
vod_id: item.id,
vod_name: item.title || '未知标题',
vod_pic: imghost ? `${imghost}${item.path || ''}` : (item.path || ''),
vod_remarks: item.mask || '',
});
}
});
return videos;
}
async function category(tid, pg, filter, extend) {
if (pg <= 0) pg = 1;
let videos = [];
if (tid === '99' || tid === 99) {
videos = await DyTag(70, pg);
} else {
let extendParams = extend || {};
let url = `${host}${rule.crumbList}?fcate_pid=${tid}&category_id=&area=${extendParams.area || ''}&year=${extendParams.year || ''}&type=${extendParams.cateId || ''}&sort=${extendParams.sort || ''}&page=${pg}`;
let html = await request(url);
if (html) {
let parsed = safeJSONParse(html);
let res = parsed.data;
if (res && Array.isArray(res)) {
res.forEach(item => {
if (item) {
videos.push({
vod_id: item.id,
vod_name: item.title || '未知标题',
vod_pic: imghost ? `${imghost}${item.path || ''}` : (item.path || ''),
vod_remarks: item.mask || '',
});
}
});
}
}
}
let filteredVideos = [];
videos.forEach(item => {
if (!item.vod_name) return;
const title = item.vod_name;
const isBadTitle = title_remove.some(word => new RegExp(word, 'i').test(title));
if (!isBadTitle) {
filteredVideos.push(item);
}
});
return JSON.stringify({
page: parseInt(pg),
pagecount: 99999,
limit: filteredVideos.length,
total: 99999,
list: filteredVideos
});
}
async function detail(id) {
let html = await request(`${host}${rule.detail}?id=${id}`);
if (!html) {
return JSON.stringify({ list: [] });
}
let parsed = safeJSONParse(html);
let res = parsed.data;
if (!res) {
return JSON.stringify({ list: [] });
}
let playForm = [];
let playUrls = [];
if (res.source_list_source && Array.isArray(res.source_list_source)) {
res.source_list_source.forEach(item => {
if (!item) return;
const form = item.name || '未知线路';
let finalForm = form;
if (item.source_list && item.source_list.length > 0 && item.source_list[0] && item.source_list[0].url) {
let domain = extractDomain(item.source_list[0].url);
if (domain.length > 8) domain = domain.substring(0, 8);
finalForm = `${form}(${domain})`;
}
const isBadLine = line_remove.some(pattern => finalForm.toLowerCase().includes(pattern.toLowerCase()));
if (!isBadLine) {
playForm.push(finalForm);
let urls = [];
if (item.source_list && Array.isArray(item.source_list)) {
item.source_list.forEach(source => {
if (source && source.source_name && source.url) {
urls.push(`${source.source_name}$${source.url}`);
}
});
}
playUrls.push(urls.join('#'));
}
});
}
let combined = [];
playForm.forEach((form, i) => {
if (playUrls[i]) {
combined.push({ form, url: playUrls[i] });
}
});
combined.sort((a, b) => {
const getPri = name => {
const idx = line_order.findIndex(k => name.toLowerCase().includes(k.toLowerCase()));
return idx === -1 ? 999 : idx;
};
return getPri(a.form) - getPri(b.form);
});
let sortedPlayForm = [];
let sortedPlayUrls = [];
combined.forEach(item => {
sortedPlayForm.push(item.form);
sortedPlayUrls.push(item.url);
});
let play_from = [];
sortedPlayForm.forEach(item => {
play_from.push(item.replace(/常规线路/g, '边下边播'));
});
const vod = {
"vod_id": id,
"vod_name": res.title || '未知标题',
"vod_year": res.year || '',
"vod_area": res.area || '',
"vod_remarks": res.mask || '',
"vod_content": res.description || '',
"vod_pic": imghost ? `${imghost}${res.thumbnail || ''}` : (res.thumbnail || ''),
"vod_play_from": play_from.join('$$$'),
"vod_play_url": sortedPlayUrls.join('$$$')
};
return JSON.stringify({ list: [vod] });
}
async function play(flag, id, flags) {
if (id && id.indexOf(".m3u8") > -1) {
return JSON.stringify({ parse: 0, url: id });
} else if (id) {
return JSON.stringify({ parse: 0, url: `tvbox-xg:${id}` });
}
return JSON.stringify({ parse: 0, url: '', msg: '播放地址为空' });
}
async function search(wd, quick, pg) {
let page = pg || 1;
let promises = [];
for (let p = page; p < page + maxPages; p++) {
let url = `${host}${rule.search}?key=${encodeURIComponent(wd)}&category_id=88&page=${p}&pageSize=20`;
promises.push(request(url, { headers, timeout: 8000 }));
}
let results = await Promise.all(promises);
let allVideos = [];
for (let html of results) {
if (!html) continue;
let parsed = safeJSONParse(html);
let res = parsed.data;
if (res && Array.isArray(res)) {
res.forEach(item => {
if (item && item.id) {
allVideos.push({
vod_id: item.id,
vod_name: item.title || '未知标题',
vod_pic: imghost ? `${imghost}${item.thumbnail || ''}` : (item.thumbnail || ''),
vod_remarks: item.mask || '',
});
}
});
}
}
let filteredVideos = [];
for (let item of allVideos) {
if (item.vod_name && new RegExp(wd, "i").test(item.vod_name)) {
filteredVideos.push(item);
}
}
return JSON.stringify({
page: page,
pagecount: maxPages,
limit: filteredVideos.length,
total: filteredVideos.length,
list: filteredVideos
});
}
function extractDomain(url) {
if (!url) return '';
const cleanUrl = url.replace(/^(https?:\/\/)?/, '');
const domainPart = cleanUrl.split('/')[0];
if (domainPart.includes('-')) {
return domainPart.split('-')[0];
}
if (domainPart.includes('.')) {
const dotParts = domainPart.split('.');
if (dotParts.length > 2) {
return dotParts[dotParts.length - 2];
} else if (dotParts.length === 2) {
return dotParts[0];
}
}
return domainPart;
}
export function __jsEvalReturn() {
return { init, home, homeVod, category, detail, play, search };
}
+607
Melihat File
@@ -0,0 +1,607 @@
/*!
* 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;
}
}
}
}));
+504
Melihat File
@@ -0,0 +1,504 @@
(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+)?$/;
var NON_PRIMITIVES = /\[[@#~](,[@#~])*\]|\[\]|\{([@i]:[@#~])(,[@i]:[@#~])*\}|\{\}/g;
var IDENTIFIERS = /[$_a-z][$\w]*/gi;
var VARIABLES = /i(\.i|\[[@#i]\])*/g;
var ACCESSOR = /(\.i|\[[@#i]\])/g;
var OPERATORS = /(===?|!==?|>=?|<=?|&&|\|\||[+\-\*\/%])/g;
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) {
var match = src.slice(index + open.length).match(TAGS[open]);
match = match ? match[0] : "";
var simplified = match.replace(STRINGS, "@");
if (!match || ~simplified.indexOf(open)) {
return index + 1
}
var inner = match.slice(0, 0 - open.length);
if (inner.charAt(0) === "-") var wsCollapseLeft = true;
if (inner.slice(-1) === "-") var wsCollapseRight = true;
inner = inner.replace(/^-|-$/g, "").trim();
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 === "{{{") {
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, "@");
extracted.src = extracted.src.replace(/\|\|/g, "~").split("|");
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]
};
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")
};
Parser.prototype.parseExpr = function(src, opts) {
opts = opts || {};
var parsed1 = this.extractEnt(src, STRINGS, "@");
parsed1.src = parsed1.src.replace(EOPS, function(s, before, op, after) {
return op in operators ? before + operators[op] + after : s
});
var parsed2 = this.extractEnt(parsed1.src, IDENTS_AND_NUMS, function(s) {
return s in constants || NUMBER.test(s) ? "#" : null
});
var parsed3 = this.extractEnt(parsed2.src, IDENTIFIERS, "i");
parsed3.src = parsed3.src.replace(/\s+/g, "");
var simplified = parsed3.src;
while (simplified !== (simplified = this.replaceComplex(simplified)));
while (simplified !== (simplified = simplified.replace(/i(\.i|\[[@#i]\])+/, "v")));
simplified = simplified.replace(/[iv]\[v?\]/g, "x");
simplified = simplified.replace(/[@#~v]/g, "i");
simplified = simplified.replace(OPERATORS, "%");
simplified = simplified.replace(/!+[i]/g, "i");
var terms = opts.terms ? simplified.split(",") : [simplified];
terms.forEach(function(term) {
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();
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(",") + ")"
};
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 + '"'
}
return JSON.parse(str)
};
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;
this.isSilent = true
},
include: function(name) {
name = this.parseQuoted(name);
var incSrc = this.readTemplateFile(name);
this.isInclude = true;
this.tokenize(incSrc);
this.isInclude = false
}
};
tagHandlers.assign = tagHandlers.set;
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
};
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;
val = filter.apply(data, arr)
} else {
throw new Error("Invalid filter: " + name)
}
}
if (opts.autoEscape && name !== opts.autoEscape && name !== "safe") {
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
};
function trimLeft(str) {
return str.replace(LEADING_SPACE, "")
}
function trimRight(str) {
return str.replace(TRAILING_SPACE, "")
}
function matchAll(str, reg, fn) {
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
}
}
}
});
+33
Melihat File
@@ -0,0 +1,33 @@
var rule = {
title:'JRKAN直播',
host:'http://www.jrs80.com/?lan=1',
// JRKAN备用域名:www.jrkankan.com / www.jrkan365.com / jrsyyds.com / www.jryyds.com / jrskan.com / jrsbxj.com /Jrkan备用域名1: www.jrkan2022.com 备用域名2: www.jrs23.com 备用域名2: www.jrskk.com 最新网址发布:www.qiumi1314.co
url:'/fyclass',
searchUrl:'/x/search/?q=**',
searchable:1,
quickSearch:1,
class_name:'全部',
class_url:'/',
//class_url:'?live',
headers:{
'User-Agent':'MOBILE_UA'
},
timeout:5000,
play_parse:true,
lazy:"",
limit:6,
double:false,
推荐:'*',
// 一级:'.loc_match:eq(2) ul;li:gt(1):lt(4)&&Text;img&&src;li:lt(2)&&Text;a:eq(1)&&href',//play.sportsteam333.com
一级:"js:var items=[];pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd;var html=request(input);var tabs=pdfa(html,'body&&.d-touch');tabs.forEach(function(it){var pz=pdfh(it,'.name:eq(1)&&Text');var ps=pdfh(it,'.name:eq(0)&&Text');var pk=pdfh(it,'.name:eq(2)&&Text');var img=pd(it,'img&&src');var url=pd(it,'a.me&&href');var timer=pdfh(it,'.lab_time&&Text');var parts = timer.split(' ');var dateParts = parts[0].split('-');var timeParts = parts[1].split(':');var year = new Date().getFullYear();var date = new Date(year, dateParts[0] - 1, dateParts[1], timeParts[0], timeParts[1]);var now = new Date();var hundredMinutesAgo = new Date(now.getTime() - 100 * 60 * 1000);if (date > hundredMinutesAgo) {timer = timer.split(' ')[1];items.push({desc:timer+ ' '+'🏆'+ps,title:pz+' 🆚 '+pk,pic_url:img,url:url})}});setResult(items);",
二级:{
"title":".sub_list li:lt(2)&&Text;.sub_list li:eq(0)&&Text",
"img":"img&&src",
"desc":";;;.lab_team_home&&Text;.lab_team_away&&Text",
"content":".sub_list ul&&Text",
"tabs":"js:TABS=['实时直播']",
"lists":"js:LISTS=[];pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd;let html=request(input);let data=pdfa(html,'.sub_playlist&&a');TABS.forEach(function(tab){let d=data.map(function(it){let name=pdfh(it,'strong&&Text');let url=pd(it,'a&&data-play');return name+'$'+url});LISTS.push(d)});",
},
搜索:'js:let d=[];setResult(d);',
}