mirror of https://github.com/qist/tvbox.git
parent
3bd977610f
commit
a4a2ad66fc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,130 @@
|
|||||||
|
var rule = {
|
||||||
|
title: 'kk小站',
|
||||||
|
host: 'http://127.0.0.1:10079',
|
||||||
|
homeUrl: '/p/0/socks5:%252F%252F192.168.101.1:1080/https://kkxz.vip/',
|
||||||
|
url: '/p/0/socks5:%252F%252F192.168.101.1:1080/https://kkxz.vip/t/fyclass?',
|
||||||
|
filter_url: '{{fl.class}}',
|
||||||
|
filter: {},
|
||||||
|
searchUrl: '/p/0/socks5:%252F%252F192.168.101.1:1080/https://kkxz.vip/?q=**',
|
||||||
|
searchable: 2,
|
||||||
|
quickSearch: 1,
|
||||||
|
filterable: 0,
|
||||||
|
headers: {
|
||||||
|
'User-Agent': PC_UA,
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Cookie':'http://127.0.0.1:9978/file:///tvbox/JS/lib/kkxz.txt',
|
||||||
|
'Referer': 'https://kkxz.vip/'
|
||||||
|
},
|
||||||
|
|
||||||
|
class_name: '電視劇&電影',
|
||||||
|
class_url: 'tv&movie',
|
||||||
|
play_parse: true,
|
||||||
|
play_json: [{
|
||||||
|
re: '*',
|
||||||
|
json: {
|
||||||
|
parse: 0,
|
||||||
|
jx: 0
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
lazy: '',
|
||||||
|
limit: 6,
|
||||||
|
推荐: '',
|
||||||
|
一级: 'div.DiscussionList li;h3&&Text;img&src;;a&&href',
|
||||||
|
二级: {
|
||||||
|
title: "h2&&Text",
|
||||||
|
img: "img&&src",
|
||||||
|
desc: "p&&Text",
|
||||||
|
content: "p&&Text",
|
||||||
|
tabs: `js: pdfh = jsp.pdfh;
|
||||||
|
pdfa = jsp.pdfa;
|
||||||
|
pd = jsp.pd;
|
||||||
|
TABS = [];
|
||||||
|
let d = pdfa(html, '.Post-body p a');
|
||||||
|
let tabsa = [];
|
||||||
|
let tabsq = [];
|
||||||
|
let tabsm = false;
|
||||||
|
let tabse = false;
|
||||||
|
d.forEach(function(it) {
|
||||||
|
let burl = pdfh(it, 'a&&href');
|
||||||
|
if (burl.startsWith("https://www.aliyundrive.com/s/")) {
|
||||||
|
tabsa.push("阿里云盤");
|
||||||
|
} else if (burl.startsWith("https://pan.quark.cn/s/")) {
|
||||||
|
tabsq.push("夸克云盤");
|
||||||
|
} else if (burl.startsWith("magnet")) {
|
||||||
|
tabsm = true;
|
||||||
|
} else if (burl.startsWith("ed2k")) {
|
||||||
|
tabse = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (tabsm === true) {
|
||||||
|
TABS.push("磁力");
|
||||||
|
}
|
||||||
|
if (tabse === true) {
|
||||||
|
TABS.push("電驢");
|
||||||
|
}
|
||||||
|
let tmpIndex;
|
||||||
|
tmpIndex = 1;
|
||||||
|
tabsa.forEach(function(it) {
|
||||||
|
TABS.push(it + tmpIndex);
|
||||||
|
tmpIndex = tmpIndex + 1;
|
||||||
|
});
|
||||||
|
tmpIndex = 1;
|
||||||
|
tabsq.forEach(function(it) {
|
||||||
|
TABS.push(it + tmpIndex);
|
||||||
|
tmpIndex = tmpIndex + 1;
|
||||||
|
});
|
||||||
|
log('alyps TABS >>>>>>>>>>>>>>>>>>' + TABS);`,
|
||||||
|
lists: `js: log(TABS);
|
||||||
|
pdfh = jsp.pdfh;
|
||||||
|
pdfa = jsp.pdfa;
|
||||||
|
pd = jsp.pd;
|
||||||
|
LISTS = [];
|
||||||
|
let d = pdfa(html, '.Post-body p a');
|
||||||
|
let lista = [];
|
||||||
|
let listq = [];
|
||||||
|
let listm = [];
|
||||||
|
let liste = [];
|
||||||
|
d.forEach(function(it) {
|
||||||
|
let burl = pdfh(it, 'a&&href');
|
||||||
|
let title = pdfh(it, 'a&&Text');
|
||||||
|
log('alyps title >>>>>>>>>>>>>>>>>>>>>>>>>>' + title);
|
||||||
|
log('alyps burl >>>>>>>>>>>>>>>>>>>>>>>>>>' + burl);
|
||||||
|
let loopresult = title + '$' + burl;
|
||||||
|
if (burl.startsWith("https://www.aliyundrive.com/s/")) {
|
||||||
|
if (TABS.length == 1) {
|
||||||
|
burl = "http://127.0.0.1:9978/proxy?do=ali&type=push&confirm=0&url=" + encodeURIComponent(burl);
|
||||||
|
} else {
|
||||||
|
burl = "http://127.0.0.1:9978/proxy?do=ali&type=push&url=" + encodeURIComponent(burl);
|
||||||
|
}
|
||||||
|
loopresult = title + '$' + burl;
|
||||||
|
lista.push(loopresult);
|
||||||
|
} else if (burl.startsWith("https://pan.quark.cn/s/")) {
|
||||||
|
if (TABS.length == 1) {
|
||||||
|
burl = "http://127.0.0.1:9978/proxy?do=quark&type=push&confirm=0&url=" + encodeURIComponent(burl);
|
||||||
|
} else {
|
||||||
|
burl = "http://127.0.0.1:9978/proxy?do=quark&type=push&url=" + encodeURIComponent(burl);
|
||||||
|
}
|
||||||
|
loopresult = title + '$' + burl;
|
||||||
|
listq.push(loopresult);
|
||||||
|
} else if (burl.startsWith("magnet")) {
|
||||||
|
listm.push(loopresult);
|
||||||
|
} else if (burl.startsWith("ed2k")) {
|
||||||
|
liste.push(loopresult);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (listm.length > 0) {
|
||||||
|
LISTS.push(listm.reverse());
|
||||||
|
}
|
||||||
|
if (liste.length > 0) {
|
||||||
|
LISTS.push(liste.reverse());
|
||||||
|
}
|
||||||
|
lista.forEach(function(it) {
|
||||||
|
LISTS.push([it]);
|
||||||
|
});
|
||||||
|
listq.forEach(function(it) {
|
||||||
|
LISTS.push([it]);
|
||||||
|
});`,
|
||||||
|
|
||||||
|
},
|
||||||
|
搜索: 'div.Discussionlist li;h3&&Text;img&&src;span.TagLabel-text;a&&href',
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
var rule = {
|
||||||
|
title:'奇妙搜[夸]',
|
||||||
|
host:'https://www.magicalsearch.top',
|
||||||
|
homeUrl:'/',
|
||||||
|
url: '/search?',
|
||||||
|
filter_url:'{{fl.class}}',
|
||||||
|
filter:{
|
||||||
|
},
|
||||||
|
搜索编码: 'utf-8',
|
||||||
|
searchUrl: '/api/pshou/getData?type=%E9%98%BF%E9%87%8C%E7%BD%91%E7%9B%98&word=**',
|
||||||
|
searchable:2,
|
||||||
|
quickSearch:0,
|
||||||
|
filterable:0,
|
||||||
|
headers:{
|
||||||
|
'User-Agent': PC_UA,
|
||||||
|
'Accept': '*/*',
|
||||||
|
'Referer': 'https://www.magicalsearch.top/'
|
||||||
|
},
|
||||||
|
timeout:5000,
|
||||||
|
class_name:'',
|
||||||
|
class_url:'',
|
||||||
|
play_parse:true,
|
||||||
|
play_json:[{
|
||||||
|
re:'*',
|
||||||
|
json:{
|
||||||
|
parse:0,
|
||||||
|
jx:0
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
lazy:'',
|
||||||
|
limit:6,
|
||||||
|
推荐:'',
|
||||||
|
一级:'',
|
||||||
|
二级:`js:
|
||||||
|
VOD.vod_play_from = "網盤";
|
||||||
|
VOD.vod_remarks = detailUrl;
|
||||||
|
VOD.vod_actor = "沒有二級,只有一級鏈接直接推送播放";
|
||||||
|
VOD.vod_content = MY_URL;
|
||||||
|
VOD.vod_play_url = "播放$" + detailUrl;
|
||||||
|
`,
|
||||||
|
搜索:`js:
|
||||||
|
let new_html=request(input);
|
||||||
|
//log("qimiao search result>>>>>>>>>>>>>>>" + new_html);
|
||||||
|
let json=JSON.parse(JSON.parse(new_html));
|
||||||
|
json = json.result.items;
|
||||||
|
let d=[];
|
||||||
|
for(const it in json){
|
||||||
|
if (json.hasOwnProperty(it)){
|
||||||
|
log("qimiao search it>>>>>>>>>>>>>>>" + JSON.stringify(json[it]));
|
||||||
|
if (json[it].title.includes(KEY)){
|
||||||
|
d.push({
|
||||||
|
title:json[it].title,
|
||||||
|
img:'',
|
||||||
|
content:json[it].content.title,
|
||||||
|
desc:json[it].insert_time,
|
||||||
|
url:'push://'+json[it].page_url
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setResult(d);
|
||||||
|
`,
|
||||||
|
}
|
||||||
@ -1,266 +0,0 @@
|
|||||||
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
|
|
||||||
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
|
|
||||||
// !!!!! Do not use in release mode. Just a native inject fake wrapper for test spider. !!!!!
|
|
||||||
import axios from 'axios';
|
|
||||||
import crypto from 'crypto';
|
|
||||||
import https from 'https';
|
|
||||||
import fs from 'node:fs';
|
|
||||||
import qs from 'qs';
|
|
||||||
import { Uri, _ } from '../lib/cat.js';
|
|
||||||
|
|
||||||
const confs = {};
|
|
||||||
|
|
||||||
function initLocalStorage(storage) {
|
|
||||||
if (!_.has(confs, storage)) {
|
|
||||||
if (!fs.existsSync('local')) {
|
|
||||||
fs.mkdirSync('local');
|
|
||||||
}
|
|
||||||
|
|
||||||
const storagePath = 'local/js_' + storage;
|
|
||||||
|
|
||||||
if (!fs.existsSync(storagePath)) {
|
|
||||||
fs.writeFileSync(storagePath, '{}');
|
|
||||||
confs[storage] = {};
|
|
||||||
} else {
|
|
||||||
confs[storage] = JSON.parse(fs.readFileSync(storagePath).toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function localGet(storage, key) {
|
|
||||||
initLocalStorage(storage);
|
|
||||||
return _.get(confs[storage], key, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function localSet(storage, key, value) {
|
|
||||||
initLocalStorage(storage);
|
|
||||||
confs[storage][key] = value;
|
|
||||||
fs.writeFileSync('local/js_' + storage, JSON.stringify(confs[storage]));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function request(url, opt) {
|
|
||||||
try {
|
|
||||||
var data = opt ? opt.data || null : null;
|
|
||||||
var postType = opt ? opt.postType || null : null;
|
|
||||||
var returnBuffer = opt ? opt.buffer || 0 : 0;
|
|
||||||
var timeout = opt ? opt.timeout || 5000 : 5000;
|
|
||||||
|
|
||||||
var headers = opt ? opt.headers || {} : {};
|
|
||||||
if (postType == 'form') {
|
|
||||||
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
||||||
|
|
||||||
if (data != null) {
|
|
||||||
data = qs.stringify(data, { encode: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let respType = returnBuffer == 1 || returnBuffer == 2 ? 'arraybuffer' : undefined;
|
|
||||||
var resp = await axios(url, {
|
|
||||||
responseType: respType,
|
|
||||||
method: opt ? opt.method || 'get' : 'get',
|
|
||||||
headers: headers,
|
|
||||||
data: data,
|
|
||||||
timeout: timeout,
|
|
||||||
httpsAgent: https.Agent({
|
|
||||||
rejectUnauthorized: false,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
var data = resp.data;
|
|
||||||
|
|
||||||
var resHeader = {};
|
|
||||||
for (const hks of resp.headers) {
|
|
||||||
var v = hks[1];
|
|
||||||
resHeader[hks[0]] = Array.isArray(v) ? (v.length == 1 ? v[0] : v) : v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!returnBuffer) {
|
|
||||||
if (typeof data === 'object') {
|
|
||||||
data = JSON.stringify(data);
|
|
||||||
}
|
|
||||||
} else if (returnBuffer == 1) {
|
|
||||||
return { code: resp.status, headers: resHeader, content: data };
|
|
||||||
} else if (returnBuffer == 2) {
|
|
||||||
return { code: resp.status, headers: resHeader, content: data.toString('base64') };
|
|
||||||
}
|
|
||||||
return { code: resp.status, headers: resHeader, content: data };
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
return { headers: {}, content: '' };
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64EncodeBuf(buff, urlsafe = false) {
|
|
||||||
return buff.toString(urlsafe ? 'base64url' : 'base64');
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64Encode(text, urlsafe = false) {
|
|
||||||
return base64EncodeBuf(Buffer.from(text, 'utf8'), urlsafe);
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64DecodeBuf(text) {
|
|
||||||
return Buffer.from(text, 'base64');
|
|
||||||
}
|
|
||||||
|
|
||||||
function base64Decode(text) {
|
|
||||||
return base64DecodeBuf(text).toString('utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
function md5(text) {
|
|
||||||
return crypto.createHash('md5').update(Buffer.from(text, 'utf8')).digest('hex');
|
|
||||||
}
|
|
||||||
|
|
||||||
function aes(mode, encrypt, input, inBase64, key, iv, outBase64) {
|
|
||||||
if (iv.length == 0) iv = null;
|
|
||||||
try {
|
|
||||||
if (mode.startsWith('AES/CBC')) {
|
|
||||||
switch (key.length) {
|
|
||||||
case 16:
|
|
||||||
mode = 'aes-128-cbc';
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
mode = 'aes-256-cbc';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (mode.startsWith('AES/ECB')) {
|
|
||||||
switch (key.length) {
|
|
||||||
case 16:
|
|
||||||
mode = 'aes-128-ecb';
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
mode = 'aes-256-ecb';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
|
|
||||||
let keyBuf = Buffer.from(key);
|
|
||||||
if (keyBuf.length < 16) keyBuf = Buffer.concat([keyBuf], 16);
|
|
||||||
let ivBuf = iv == null ? Buffer.alloc(0) : Buffer.from(iv);
|
|
||||||
if (iv != null && ivBuf.length < 16) ivBuf = Buffer.concat([ivBuf], 16);
|
|
||||||
const cipher = encrypt ? crypto.createCipheriv(mode, keyBuf, ivBuf) : crypto.createDecipheriv(mode, keyBuf, ivBuf);
|
|
||||||
const outBuf = Buffer.concat([cipher.update(inBuf), cipher.final()]);
|
|
||||||
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function des(mode, encrypt, input, inBase64, key, iv, outBase64) {
|
|
||||||
try {
|
|
||||||
if (mode.startsWith('DESede/CBC')) {
|
|
||||||
// https://stackoverflow.com/questions/29831300/convert-desede-ecb-nopadding-algorithm-written-in-java-into-nodejs-using-crypto
|
|
||||||
switch (key.length) {
|
|
||||||
case 16:
|
|
||||||
mode = 'des-ede-cbc';
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
mode = 'des-ede3-cbc';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
|
|
||||||
let keyBuf = Buffer.from(key);
|
|
||||||
if (keyBuf.length < 16) keyBuf = Buffer.concat([keyBuf], 16);
|
|
||||||
let ivBuf = iv == null ? Buffer.alloc(0) : Buffer.from(iv);
|
|
||||||
if (iv != null && ivBuf.length < 8) ivBuf = Buffer.concat([ivBuf], 8);
|
|
||||||
const cipher = encrypt ? crypto.createCipheriv(mode, keyBuf, ivBuf) : crypto.createDecipheriv(mode, keyBuf, ivBuf);
|
|
||||||
const outBuf = Buffer.concat([cipher.update(inBuf), cipher.final()]);
|
|
||||||
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// pkcs8 only
|
|
||||||
function rsa(mode, pub, encrypt, input, inBase64, key, outBase64) {
|
|
||||||
try {
|
|
||||||
let pd = undefined;
|
|
||||||
const keyObj = pub ? crypto.createPublicKey(key) : crypto.createPrivateKey(key);
|
|
||||||
if (!keyObj.asymmetricKeyDetails || !keyObj.asymmetricKeyDetails.modulusLength) return '';
|
|
||||||
const moduleLen = keyObj.asymmetricKeyDetails.modulusLength;
|
|
||||||
let blockLen = moduleLen / 8;
|
|
||||||
switch (mode) {
|
|
||||||
case 'RSA/PKCS1':
|
|
||||||
pd = crypto.constants.RSA_PKCS1_PADDING;
|
|
||||||
blockLen = encrypt ? blockLen - 11 : blockLen;
|
|
||||||
break;
|
|
||||||
case 'RSA/None/NoPadding':
|
|
||||||
pd = crypto.constants.RSA_NO_PADDING;
|
|
||||||
break;
|
|
||||||
case 'RSA/None/OAEPPadding':
|
|
||||||
pd = crypto.constants.RSA_PKCS1_OAEP_PADDING;
|
|
||||||
blockLen = encrypt ? blockLen - 41 : blockLen;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw Error('not support ' + mode);
|
|
||||||
}
|
|
||||||
let inBuf = inBase64 ? base64DecodeBuf(input) : Buffer.from(input, 'utf8');
|
|
||||||
let bufIdx = 0;
|
|
||||||
let outBuf = Buffer.alloc(0);
|
|
||||||
while (bufIdx < inBuf.length) {
|
|
||||||
const bufEndIdx = Math.min(bufIdx + blockLen, inBuf.length);
|
|
||||||
let tmpInBuf = inBuf.subarray(bufIdx, bufEndIdx);
|
|
||||||
if (pd == crypto.constants.RSA_NO_PADDING) {
|
|
||||||
if (tmpInBuf.length < blockLen) {
|
|
||||||
tmpInBuf = Buffer.concat([Buffer.alloc(128 - tmpInBuf.length), tmpInBuf]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let tmpBuf;
|
|
||||||
if (pub) {
|
|
||||||
tmpBuf = encrypt ? crypto.publicEncrypt({ key: keyObj, padding: pd }, tmpInBuf) : crypto.publicDecrypt({ key: keyObj, padding: pd }, tmpInBuf);
|
|
||||||
} else {
|
|
||||||
tmpBuf = encrypt ? crypto.privateEncrypt({ key: keyObj, padding: pd }, tmpInBuf) : crypto.privateDecrypt({ key: keyObj, padding: pd }, tmpInBuf);
|
|
||||||
}
|
|
||||||
bufIdx = bufEndIdx;
|
|
||||||
outBuf = Buffer.concat([outBuf, tmpBuf]);
|
|
||||||
}
|
|
||||||
return outBase64 ? base64EncodeBuf(outBuf) : outBuf.toString('utf8');
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
|
|
||||||
|
|
||||||
function randStr(len, withNum) {
|
|
||||||
var _str = '';
|
|
||||||
let containsNum = withNum === undefined ? true : withNum;
|
|
||||||
for (var i = 0; i < len; i++) {
|
|
||||||
let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
|
|
||||||
_str += charStr[idx];
|
|
||||||
}
|
|
||||||
return _str;
|
|
||||||
}
|
|
||||||
|
|
||||||
globalThis.local = {
|
|
||||||
get: async function (storage, key) {
|
|
||||||
return localGet(storage, key);
|
|
||||||
},
|
|
||||||
set: async function (storage, key, val) {
|
|
||||||
localSet(storage, key, val);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
globalThis.md5X = md5;
|
|
||||||
globalThis.rsaX = rsa;
|
|
||||||
globalThis.aesX = aes;
|
|
||||||
globalThis.desX = des;
|
|
||||||
|
|
||||||
globalThis.req = request;
|
|
||||||
|
|
||||||
globalThis.url2Proxy = async function (type, url, headers) {
|
|
||||||
let hd = Object.keys(headers).length == 0 ? '_' : encodeURIComponent(JSON.stringify(headers));
|
|
||||||
let uri = new Uri(url);
|
|
||||||
let path = uri.path();
|
|
||||||
path = path.substring(path.lastIndexOf('/'));
|
|
||||||
let ext = path.indexOf('.') >= 0 ? path.substring(path.indexOf('.')) : '.bin';
|
|
||||||
return 'http://127.0.0.1:13333/up/' + randStr(6) + '/' + type + '/' + hd + '/' + encodeURIComponent(url) + '/' + ext;
|
|
||||||
};
|
|
||||||
|
|
||||||
globalThis.js2Proxy = async function (dynamic, siteType, site, url, headers) {
|
|
||||||
let hd = Object.keys(headers).length == 0 ? '_' : encodeURIComponent(JSON.stringify(headers));
|
|
||||||
return (dynamic ? 'js2p://_WEB_/' : 'http://127.0.0.1:13333/jp/') + randStr(6) + '/' + siteType + '/' + site + '/' + hd + '/' + encodeURIComponent(url);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {};
|
|
||||||
Loading…
Reference in new issue