上传文件至「js」
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
title: '厂长资源', author: '小可乐/v6.1.1'
|
||||
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
|
||||
"ext": {
|
||||
"host": "xxxx", //站点网址
|
||||
"timeout": 6000 //请求超时,单位毫秒
|
||||
}
|
||||
*/
|
||||
|
||||
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.cz01.org').replace(/\/$/, '');
|
||||
KParams.headers['Referer'] = HOST;
|
||||
let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10);
|
||||
if (parseTimeout > 0) {KParams.timeout = parseTimeout;}
|
||||
} catch (e) {
|
||||
console.error('初始化参数失败:', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function home(filter) {
|
||||
try {
|
||||
let kclassName = '全部$movie_bt&电影$movie_bt_series/dyy&剧集$movie_bt_series/dianshiju&动画$movie_bt_series/dohua';
|
||||
let classes = kclassName.split('&').map(it => {
|
||||
let [cName, cId] = it.split('$');
|
||||
return {type_name: cName, type_id: cId};
|
||||
});
|
||||
let filters = {};
|
||||
try {
|
||||
const nameObj = { cateId: 'cateId,分类', area: 'area,地区', year: 'year,年份', class: 'class,影片类型', series: 'series,子类'};
|
||||
const flValues = {
|
||||
cateId: {'movie_bt_series/dyy': '全部$movie_bt_series/dyy&豆瓣电影Top250$dbtop250&最新电影$zuixindianying&高分影视$gaofenyingshi&热映中$reyingzhong&会员专区$movie_bt_series/huiyuanzhuanqu&站长推荐$movie_bt_series/zhanchangtuijian&华语电影$movie_bt_series/huayudianying&欧美电影$movie_bt_series/meiguodianying&韩国电影$movie_bt_series/hanguodianying&日本电影$movie_bt_series/ribendianying&印度电影$movie_bt_series/yindudianying&俄罗斯电影$movie_bt_series/eluosidianying&加拿大电影$movie_bt_series/jianadadianying', 'movie_bt_series/dianshiju': '全部$movie_bt_series/dianshiju&国产剧$gcj&美剧$meijutt&韩剧$hanjutv&日剧$movie_bt_series/rj&海外剧$movie_bt_series/hwj', 'movie_bt_series/dohua': '全部$movie_bt_series/dohua&剧场版$dongmanjuchangban&番剧$fanju'},
|
||||
area: {'movie_bt': '全部$&中国台湾$tw&中国大陆$zh&中国香港$hk&丹麦$dm&乌克兰$wukelan&以色列$ysl&伊朗$yilang&俄罗斯$els&保加利亚$baojialiya&其他$qt&冰岛$冰岛&利比里亚$libiliya&加拿大$jnd&匈牙利$xiongyali&南非$nanfei&卡塔尔$kataer&卢森堡$lusenbao&印度$yidu&印度尼西亚$yindunixiya&哈萨克斯坦$hasakesitan&哥伦比亚$gelunbiya&土耳其$tuerqi&埃及$aiji&塞尔维亚$塞尔维亚&塞浦路斯$saipulusi&墨西哥$mxg&奥地利$aodili&巴哈马$bahama&巴基斯坦$bajisitan&巴西$bx&希腊$xila&德国$dg&意大利$ydl&拉脱维亚$拉脱维亚&挪威$nuewei&捷克$jieke&摩洛哥$moluoge&摩纳哥$monage&新加坡$xinjiapo&新西兰$xinxilan&日本$riben&柬埔寨$jianpuzhai&比利时$bilishi&法国$fg&波兰$bolan&泰国$taiguo&澳大利亚$adly&爱尔兰$aierlan&瑞典$ruidian&瑞士$ruishi&白俄罗斯$baieluosi&立陶宛$立陶宛&罗马尼亚$luomaniya&美国$meiguo&芬兰$fenlan&英国$yinguo&荷兰$hnwe&蒙古$menggu&西德$xide&西班牙$xby&越南$yuenan&阿根廷$agenting&阿联酋$alianqiu&韩国$hggggg&马来西亚$malaixiya&马耳他$maerta&黎巴嫩$libanen'},
|
||||
year: {'movie_bt': '全部$&1900~2000年代$19002000nd&2001~2010年代$20012010nd&2011$2011nd&2012$2012&2013$2013&2014$2014&2015$2015&2016$2016&2017$2017&2018$2018&2019$2019&2020$2020&2021$2021&2022$2022&2023$2023&2024$2024&2025$2025&2026$2026'},
|
||||
class: {'movie_bt': '全部$&传记$chuanji&儿童$etet&冒险$maoxian&剧情$juqing&动作$dozuo&动漫$doman&动画$dhh&历史$lishi&古装$guzhuang&同性$tongxing&喜剧$xiju&奇幻$qihuan&家庭$jiating&恐怖$kubu&悬疑$xuanyi&情色$qingse&惊悚$kingsong&战争$zhanzheng&歌舞$gw&武侠$wuxia&灾难$zainan&爱情$aiqing&犯罪$fanzui&真人秀$zrx&短片$dp&科幻$kh&纪录片$jlpp&西部$xb&运动$yd&音乐$yy&鬼怪$鬼怪'},
|
||||
series: {'movie_bt': '全部$&会员专区$huiyuanzhuanqu&站长推荐$zhanchangtuijian&电影$dyy&华语电影$huayudianying&欧美电影$meiguodianying&韩国电影$hanguodianying&日本电影$ribendianying&印度电影$yindudianying&俄罗斯电影$eluosidianying&加拿大电影$jianadadianying&电视剧$dianshiju&国产剧$guochanju&美剧$mj&韩剧$hj&日剧$rj&海外剧(其他)$hwj&动画$dohua'}
|
||||
};
|
||||
for (let item of classes) {
|
||||
filters[item.type_id] = Object.entries(nameObj).map(([nObjk, nObjv]) => {
|
||||
let [kkey, kname] = nObjv.split(',');
|
||||
let fvalue = flValues[kkey]?.[item.type_id]?.split('&') || [];
|
||||
let kvalue = fvalue.map(it => {
|
||||
let [n, v] = it.split('$');
|
||||
return {n: n, v: v};
|
||||
});
|
||||
return {key: kkey, name: kname, value: kvalue};
|
||||
}).filter(flt => flt.key && flt.value.length);
|
||||
}
|
||||
} 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 = 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 ? extend : {};
|
||||
let cateUrl = `${HOST}/${fl.cateId || tid}${fl.area ? `/movie_bt_cat/${fl.area}` : ''}${fl.year ? `/year/${fl.year}` : ''}${fl.class ? `/movie_bt_tags/${fl.class}` : ''}${fl.series ? `/movie_bt_series/${fl.series}` : ''}/page/${pg}`;
|
||||
let resHtml = await request(cateUrl);
|
||||
let VODS = getVodList(resHtml);
|
||||
let limit = VODS.length;
|
||||
let hasMore = cutStr(resHtml, 'pagenavi_txt">', '</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 VODS = [];
|
||||
let searchStop = false, cPage = 1, pgMax = 228;
|
||||
while (!searchStop && cPage < pgMax) {
|
||||
let batchEnd = Math.min(cPage + 10, pgMax);
|
||||
let batchUrlList = [];
|
||||
for (let page = cPage; page < batchEnd; page++) {
|
||||
batchUrlList.push(`${HOST}/movie_bt/page/${page}`);
|
||||
}
|
||||
let resHtmlList = await Promise.all(
|
||||
batchUrlList.map(async (burl) => {
|
||||
try {return await request(burl);} catch (sErr) {return '';}
|
||||
})
|
||||
);
|
||||
for (let resHtml of resHtmlList) {
|
||||
let svods = getVodList(resHtml).filter(it => it.vod_name.includes(wd));
|
||||
if (svods.length) {VODS.push(...svods)};
|
||||
}
|
||||
if (VODS.length) {searchStop = true;}
|
||||
cPage = batchEnd;
|
||||
}
|
||||
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, '<li>', '</li>', '', false, 0, true);
|
||||
for (let it of listArr) {
|
||||
let kname = cutStr(it, 'alt="', '"', '名称');
|
||||
let kpic = cutStr(it, 'data-original="', '"', '图片');
|
||||
let kremarks = cutStr(it, 'jidi">', '</') || cutStr(it, 'qb">', '</') || cutStr(it, 'furk">', '</', '状态');
|
||||
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, '"dytext', 'mi_paly_box">', '', false);
|
||||
let [ktabs, kurls] = [[], []];
|
||||
let zxArr = cutStr(resHtml, 'paly_list_btn', '</div>', '', false, 0, true);
|
||||
zxArr.forEach((item,idx) => {
|
||||
let siglUrl = cutStr(item, '<a', '/a>', '', false, 0, true).map(it => { return cutStr(it, '>', '<', 'noEpi') + '$' + cutStr(it, 'href="', '"', 'noUrl'); }).join('#');
|
||||
ktabs.push(`厂长在线${idx+1}`);
|
||||
kurls.push(siglUrl);
|
||||
});
|
||||
let twoCut = cutStr(resHtml, 'dwonBT">', '</ul>', '', false);
|
||||
if (twoCut) {
|
||||
let xzArr = cutStr(twoCut, '<li>', '</li>', '', false, 0, true);
|
||||
xzArr.forEach((item,idx) => {
|
||||
let siglUrl = cutStr(item, '<a', '/a>', '', false, 0, true).map(it => {
|
||||
let eUrl = cutStr(it, 'href="', '"', 'noUrl');
|
||||
if (!/^magnet:/.test(eUrl)) { eUrl = eUrl.replace(/#/g, '@');}
|
||||
return `${cutStr(it, 'title="', '"', 'noEpi')}$${eUrl}`;
|
||||
}).join('#');
|
||||
if (/magnet:/.test(siglUrl)) {
|
||||
ktabs.push(`下载线${idx+1}磁力`);
|
||||
} else {
|
||||
ktabs.push(`下载线${idx+1}网盘`);
|
||||
}
|
||||
kurls.push(siglUrl);
|
||||
});
|
||||
}
|
||||
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, 'yp_context">', '</div>', kname),
|
||||
vod_play_from: ktabs.join('$$$'),
|
||||
vod_play_url: kurls.join('$$$')
|
||||
};
|
||||
return JSON.stringify({list: [VOD]});
|
||||
} catch (e) {
|
||||
console.error('详情页获取失败:', e.message);
|
||||
return JSON.stringify({list: []});
|
||||
}
|
||||
}
|
||||
|
||||
async function play(flag, ids, flags) {
|
||||
try {
|
||||
let playUrl = ids;
|
||||
let kp = 0, kurl = '';
|
||||
if (/磁力/.test(flag)) {
|
||||
kurl = playUrl;
|
||||
} else if (/网盘/.test(flag)) {
|
||||
kurl = playUrl.replace(/@/g, '#');
|
||||
kurl = `push://${kurl}`;
|
||||
} else {
|
||||
let resHtml = await request(playUrl);
|
||||
kurl = cutStr(resHtml, '<iframe£src="', '"', '', false).replace(/&/g, '&');
|
||||
if (!kurl) {
|
||||
kp = 1;
|
||||
kurl = playUrl;
|
||||
} else {
|
||||
let ifrHtml = await request(kurl);
|
||||
kurl = cutStr(ifrHtml, "mysvg = '", "'");
|
||||
if (!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 = '', defVal = '', clean = true, i = 0, all = false) {
|
||||
try {
|
||||
if (typeof str !== 'string') {throw new Error('被截取对象必须为字符串');}
|
||||
const cleanStr = cs => String(cs).replace(/<[^>]*?>/g, ' ').replace(/( |[\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
|
||||
};
|
||||
}
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
title: '灯泡影视', author: '小可乐/v6.1.1'
|
||||
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
|
||||
"ext": {
|
||||
"host": "xxxx", //站点网址
|
||||
"timeout": 6000, //请求超时,单位毫秒
|
||||
"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.dp88.net').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 kclassName = '电影$3&剧集$2&动漫$4';
|
||||
let classes = kclassName.split('&').map(it => {
|
||||
let [cName, cId] = it.split('$');
|
||||
return {type_name: cName, type_id: cId};
|
||||
});
|
||||
let 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}/list/${fl.by ?? '0'}_${fl.area ?? '0'}_${fl.area ?? '0'}_${fl.class ?? '0'}_${tid}/${pg}`;
|
||||
let resHtml = await request(cateUrl);
|
||||
let VODS = getVodList(resHtml);
|
||||
let limit = VODS.length;
|
||||
let hasMore = cutStr(resHtml, 'pages">', '</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 searchUrl = `${HOST}/page/${pg}/?s=${wd}`;
|
||||
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 prefix = sch ? 'content">' : '<li><a';
|
||||
let listArr = cutStr(khtml, prefix, '</li>', '', false, 0, true);
|
||||
for (let it of listArr) {
|
||||
let kname = sch ? cutStr(it, '<h3>', '</h3>', '名称') : cutStr(it, 'alt="', '"', '名称');
|
||||
let kpic = sch ? cutStr(it, 'src="', '"', '图片') : cutStr(it, 'data-original="', '"', '图片');
|
||||
let kremarks = sch ? cutStr(it, 'int">', '</p>', '状态') : cutStr(it, 's1">', '<', '状态');
|
||||
let kyear = sch ? '' : cutStr(it, '<p>', '/');
|
||||
let kid = cutStr(it, 'href="', '"');
|
||||
if (kid) {
|
||||
kvods.push({
|
||||
vod_name: kname,
|
||||
vod_pic: kpic,
|
||||
vod_remarks: kremarks,
|
||||
vod_year: kyear,
|
||||
vod_id: `${kid}@${kname}@${kpic}`
|
||||
});
|
||||
}
|
||||
}
|
||||
return kvods;
|
||||
} catch (e) {
|
||||
console.error(`生成视频列表失败:`, e.message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function detail(ids) {
|
||||
try {
|
||||
let [id, kname, kpic] = ids.split('@');
|
||||
let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id;
|
||||
let resHtml = await request(detailUrl);
|
||||
if (!resHtml) {throw new Error('源码为空');}
|
||||
let intros = cutStr(resHtml, 'content-rt">', '<section', '', false);
|
||||
let [ktabs, kurls] = [[], []];
|
||||
let zxTwoCut = cutStr(resHtml, 'pd-tit-0">', 'pd-item"', '', false);
|
||||
let zxArr = cutStr(zxTwoCut, 'tabid£>', '</ul>', '', false, 0, true)
|
||||
if (zxArr[0]) {
|
||||
zxArr.forEach((item,idx) => {
|
||||
let siglUrl = cutStr(item, '<a', '/a>', '', false, 0, true).map(it => `${cutStr(it, '>', '<', 'noEpi')}$${cutStr(it, 'href="', '"', 'noUrl')}` ).join('#');
|
||||
kurls.push(siglUrl);
|
||||
});
|
||||
cutStr(zxTwoCut, '<option', '/option>', '', false, 0, true).forEach((it,idx) => {
|
||||
ktabs.push(cutStr(it, '>', '<', `在线${idx+1}`));
|
||||
});
|
||||
}
|
||||
let clTwoCut = cutStr(resHtml, 'pd-tit-1">', 'pd-item"', '', false);
|
||||
let clArr = cutStr(clTwoCut, 'lip">', '</ul>', '', false, 0, true);
|
||||
if (clArr[0]) {
|
||||
clArr.forEach((item,idx) => {
|
||||
let siglUrl = cutStr(item, '<a', '/a>', '', false, 0, true).map(it => `${cutStr(it, 'title="', '"', 'noEpi')}$${cutStr(it, 'href="', '"', 'noUrl')}` ).join('#');
|
||||
kurls.push(siglUrl);
|
||||
});
|
||||
cutStr(clTwoCut, '<h2', 'h2>', '', false, 0, true).forEach((it,idx) => {
|
||||
ktabs.push(`磁力${idx+1}-${cutStr(it, '>', '</', '线')}`);
|
||||
});
|
||||
}
|
||||
let wpTwoCut = cutStr(resHtml, 'pd-tit-2">', '</section>', '', false);
|
||||
let wpArr = cutStr(wpTwoCut, 'lip">', '</ul>', '', false, 0, true);
|
||||
if (wpArr[0]) {
|
||||
wpArr.forEach((item,idx) => {
|
||||
let siglUrl = cutStr(item, '<a', '/a>', '', false, 0, true).map(it => `${cutStr(it, 'title="', '"', 'noEpi')}$${cutStr(it, 'href="', '"', 'noUrl')}` ).join('#');
|
||||
kurls.push(siglUrl);
|
||||
});
|
||||
cutStr(wpTwoCut, '<h2', 'h2>', '', false, 0, true).forEach((it,idx) => {
|
||||
ktabs.push(`网盘${idx+1}-${cutStr(it, '>', '</', '线')}`);
|
||||
});
|
||||
}
|
||||
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: cutStr(intros, '更新:', '</p>', '状态'),
|
||||
type_name: cutStr(intros, '类型:', '</p>', '类型'),
|
||||
vod_year: cutStr(intros, 'year">(', ')', '1000'),
|
||||
vod_area: cutStr(intros, '地区:', '</p>', '地区'),
|
||||
vod_lang: cutStr(intros, '语言:', '</p>', '语言'),
|
||||
vod_director: cutStr(intros, '导演:', '</p>', '导演'),
|
||||
vod_actor: cutStr(intros, '主演:', '</p>', '主演'),
|
||||
vod_content: cutStr(intros, 'sq_a"£>', '<span', 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 if (/网盘/.test(flag)) {
|
||||
kurl = `push://${ids}`;
|
||||
} else {
|
||||
let resHtml = await request(ids);
|
||||
kurl = cutStr(resHtml, '<iframe£url=', '"') || cutStr(resHtml, '<iframe£src="', '"');
|
||||
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.flatMap(item => set_arr.filter(it => it.type_name.includes(item)) ).filter((flt, idx, self) => self.findIndex(fdi => fdi === flt) === idx);
|
||||
return filtered_arr.length? filtered_arr : [set_arr[0]];
|
||||
} catch (e) {
|
||||
console.error('ctSet 执行异常:', e.message);
|
||||
return kArr;
|
||||
}
|
||||
}
|
||||
|
||||
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(/( |[\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
|
||||
};
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
var rule = {
|
||||
title:'爱上你听书网',
|
||||
host:'https://www.230ts.net',
|
||||
url:'/sort/fyclass/fypage.html',
|
||||
searchUrl:'/search.html?searchtype=name&searchword=**&page=fypage',
|
||||
searchable:2,
|
||||
quickSearch:0,
|
||||
headers:{
|
||||
'User-Agent':'PC_UA'
|
||||
},
|
||||
timeout:5000,
|
||||
class_parse: '.nav-ol&&li:gt(0):lt(6);a&&Text;a&&href;.*/(\\w+).html',
|
||||
play_parse:true,
|
||||
lazy:'js:input=input.replace("www","wap")',
|
||||
limit:6,
|
||||
推荐:'#myTab_Content1&&li;.tab-book-title&&Text;*;.tab-book-author&&Text;*',
|
||||
一级:'ul.list-works&&li;.list-book-dt--span&&Text;.lazy&&data-original;.book-author:eq(2)&&a&&Text;a&&href',
|
||||
二级:{
|
||||
title:'.book-cover&&alt;.book-info&&dd--span:eq(1)&&Text',
|
||||
img:'.book-cover&&src',
|
||||
desc:'.book-info&&dd:eq(4)&&Text;;;.book-info&&dd--span:eq(3)&&Text;.book-info&&dd--span:eq(2)&&Text',
|
||||
content:'.book-des&&Text',
|
||||
tabs:'.playlist-top&&h2',
|
||||
lists:'#playlist:eq(#id)&&li',
|
||||
},
|
||||
搜索:'*',
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
var rule = {
|
||||
title: '爱看资源网',
|
||||
host: 'https://aikanzy.com/',
|
||||
url: '/fyclass-fypage.html',
|
||||
searchUrl: '/search?word=**&molds=article',
|
||||
searchable: 2,
|
||||
quickSearch: 0,
|
||||
filterable: 0,
|
||||
class_parse: '.top-bar-menu&&li;a&&Text;a&&href;.*/(.*?).html',
|
||||
tab_rename: {'KUAKE1': '夸克1', 'KUAKE11': '夸克2', 'YOUSEE1': 'UC1', 'YOUSEE11': 'UC2',},
|
||||
图片来源: '@Referer=https://aikanzy.com@User-Agent=Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36',
|
||||
play_parse: true,
|
||||
lazy: $js.toString(() => {
|
||||
//推送阿里播放 支持影视壳
|
||||
let url = input.startsWith('push://') ? input : 'push://' + input;
|
||||
input = {parse: 0, url: url};
|
||||
}),
|
||||
limit: 6,
|
||||
double: true,
|
||||
推荐: '#content;.post-list;a&&title;.lazyload&&data-src;.entry-meta&&Text;a&&href',
|
||||
一级: '#content .post-list;a&&title;.lazyload&&data-src;.entry-meta&&Text;a&&href',
|
||||
二级: {
|
||||
title: 'h1&&Text;#content&&li:eq(2)&&Text',
|
||||
img: '.shadimg img&&src',
|
||||
desc: '#content&&li:eq(2)&&Text;#content&&li:eq(3)&&Text;#content&&li:eq(4)&&Text;#content&&li:eq(0)&&Text;#content&&li:eq(1)&&Text',
|
||||
content: '#content&&p:eq(2)&&Text',
|
||||
tabs: "js:TABS=['网盘']",
|
||||
lists: '.con_ad-top&&p:eq(-1)',
|
||||
list_text: '.icon&&Text',
|
||||
list_url: 'a&&href',
|
||||
},
|
||||
搜索: '#content .post-list;.entry-title&&Text;.block-fea&&style;.entry-meta&&Text;a&&href',
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
LyoqCiAqIOW8uueDiOaOqOiNkOmdmeaAgeWIhuexu+OAguWPr+S7peWKoOW/q+mAn+W6piEhIQogKiDkuI3lu7rorq46CiAqIOS8oOWPgiA/dHlwZT11cmwmcGFyYW1zPS4uL2pzb24v6YeH6ZuGLmpzb24KICog5bu66K6u77yaCiAqIOS8oOWPgiA/dHlwZT11cmwmcGFyYW1zPS4uL2pzb24v6YeH6ZuG6Z2Z5oCBLmpzb24kMQogKiDkvKDlj4IgP3R5cGU9dXJsJnBhcmFtcz0uLi9qc29uL+mHh+mbhlt6eV3pnZnmgIEuanNvbiQxCiAqIOS8oOWPgiA/dHlwZT11cmwmcGFyYW1zPS4uL2pzb24v6YeH6ZuGW+Wvhl3pnZnmgIEuanNvbiQxCiAqIGhpcHktc2VydmVy5pSv5oyBQOaUueWQjeavlOWmgjoKICog5Lyg5Y+CID90eXBlPXVybCZwYXJhbXM9Li4vanNvbi/ph4fpm4bpnZnmgIEuanNvbiQxQOmHh+eOi+mBk+mVv1vlkIhdCiAqIOS8oOWPgiA/dHlwZT11cmwmcGFyYW1zPS4uL2pzb24v6YeH6ZuGW3p5XemdmeaAgS5qc29uJDFA6YeH546Lenlb5a+GXQogKiDkvKDlj4IgP3R5cGU9dXJsJnBhcmFtcz0uLi9qc29uL+mHh+mbhlvlr4Zd6Z2Z5oCBLmpzb25A6YeH546L5oiQ5Lq6W+Wvhl0KICogW3sibmFtZSI6IuaatOmjjui1hOa6kCIsInVybCI6Imh0dHBzOi8vYmZ6eWFwaS5jb20iLCJwYXJzZV91cmwiOiIifSx7Im5hbWUiOiLpo57liIDotYTmupAiLCJ1cmwiOiJodHRwOi8vd3d3LmZlaWRhb3p5LmNvbSIsInBhcnNlX3VybCI6IiJ9LHsibmFtZSI6Ium7keacqOiAs+i1hOa6kCIsInVybCI6Imh0dHBzOi8vd3d3LmhlaW11ZXIudHYiLCJwYXJzZV91cmwiOiIifV0KICovCmdsb2JhbFRoaXMuZ2V0UmFuZG9tSXRlbSA9IGZ1bmN0aW9uIChpdGVtcykgey8v5LuO5YiX6KGo6ZqP5py65Y+W5Ye65LiA5Liq5YWD57SgCiAgICByZXR1cm4gaXRlbXNbTWF0aC5yYW5kb20oKSAqIGl0ZW1zLmxlbmd0aCB8IDBdOwp9CnZhciBydWxlID0gewogICAgdGl0bGU6ICfph4fpm4bkuYvnjotb5ZCIXScsCiAgICBhdXRob3I6ICfpgZPplb8nLAogICAgdmVyc2lvbjogJzIwMjQwNzA2IGJldGExNycsCiAgICB1cGRhdGVfaW5mbzogYAoyMDI0MDcwNjoKMS7pnZnmgIFqc29u5pWw5o2u5pSv5oyBY2F0ZV9leGNsdWRlc+WIhuexu+WQjeensOWIl+ihqOi/h+a7pOaXoOaVsOaNruWIhuexuwoyLuabtOaWsOmHh+mbhuWIhuexu+eUn+aIkOWZqOWinuWKoOi/h+a7pOetm+mAieaooeW8jwoyMDI0MDcwNToKMS7mlK/mjIHkvKDlj4Jqc29u5ZCO6Z2i5aKe5YqgJDEg6L+Z5qC355qE6aKd5aSW5qCH6K+G77yM55So5LqO5pCc57Si57uT5p6c57K+5YeG5Yy56YWNCjIu5pSv5oyB5Lyg5Y+CanNvbuWQjumdouWinuWKoCQxJDEg6L+Z5qC355qE6aKd5aSW5qCH6K+G77yM55So5LqO5by65Yi26I635Y+W5pCc57Si5Zu+54mH44CCJDEk5LiN5pi+56S65Zu+54mH44CC6buY6K6k5piv5pCc57Si5by65Yi25pyJ5Zu+54mH55qEW+W3suWunueOsOivpuaDhemhteivt+axguS9v+eUqOaJuemHj10KMy7kv67lpI3kuoznuqfmlbDmja7ml6Dluo/ljLnphY3mkJzntKLliJfooajlm77niYfnmoTpl67popgKNC7kv67mlLnmkJzntKLnsr7lh4blkozlm77niYfmmL7npLrpop3lpJblj4LmlbDpl7TpmpTnrKbku44j5Y+Y5Li6JAoyMDI0MDcwMzoKMS7ph4fpm4Zqc29u5pSv5oyBInNlYXJjaGFibGUiOiAwLOeUqOS6juaQnOe0ouaXtuaOkumZpOi/meS4qua6kAoyMDI0MDYwNDoKMS7pppbpobXmjqjojZDlj5bmtojnoazmjqfnrYnlvoXjgILlop7liqDpmo/mnLrmjqjojZDlip/og73jgIIKMi7pppbpobXmjqjojZDmlrDlop7mm7TmlrDml6Xlv5fmn6XnnIvlip/og70K44CQ54m55Yir6K+05piO44CR55uu5YmN5Y+q5pSv5oyB5qCH5YeGanNvbuagvOW8j+eahOmHh+mbhuermSjotYTmupDnq5nkuIDoiKzpg73mj5Dkvpt4bWzlkoxqc29u5Lik56eN5o6l5Y+j77yM55uu5YmN5rKh5pyJ5pSv5oyBeG1s55qE5oOz5rOV77yM5rKh5LuA5LmI5b+F6KaBKQrmnInkupvotYTmupDnq5nnmoRqc29u5o6l5Y+j5LiN5piv5qCH5YeG55qEL2FwaS5waHAvcHJvdmlkZS92b2QvLOmcgOimgeiHquW3seWcqOmHh+mbhumdmeaAgS5qc29u5Lit57yW6L6R5a+55bqU55qEYXBp5bGe5oCn5aGr5YaZ5q+U5aaCOi9hcGkucGhwL3Byb3ZpZGUvdm9kL2F0L2pzb24vCuacieS6m+i1hOa6kOermeeahOmHh+mbhuaVsOaNruaYr+WKoOWvhuWQjueahOWIh+eJh+eJh+aute+8jOWPr+iDvemcgOimgemHh+mbhuermeeJueWumueahOino+aekOaOpeWPo++8jOmcgOimgeiHquW3see8lui+kWpzb27ph4znmoRwYXJzZV91cmzlsZ7mgKcK6LWE5rqQ56uZ6YOo5YiG5aSn5YiG57G75LiL5peg5pWw5o2u5b6I5q2j5bi477yM5Y+v5Lul6Ieq6KGM57yW6L6RanNvbumHjGNhdGVfZXhjbHVkZeWxnuaAp+aOkumZpOaOieiHquW3sea1i+ivlei/h+aXoOaVsOaNrueahOWIhuexuyjlsI/nqIvluo/ml6Dms5Xoh6rliqjor4bliKvvvIzlj6rog73kurrlt6XmtYvlpb3lk6rkupvliIbnsbvml6DmlbDmja4pCmAudHJpbSgpLAogICAgaG9zdDogJycsCiAgICBob21lVGlkOiAnJywgLy8g6aaW6aG15o6o6I2Q44CC5LiA6Iis5aGr5YaZ56ys5LiA5Liq6LWE5rqQ56uZ55qE5oOz6KaB55qE5o6o6I2Q5YiG57G755qEaWQu5Y+v5Lul56m6CiAgICBob21lVXJsOiAnL2FwaS5waHAvcHJvdmlkZS92b2QvP2FjPWRldGFpbCZ0PXt7cnVsZS5ob21lVGlkfX0nLAogICAgZGV0YWlsVXJsOiAnL2FwaS5waHAvcHJvdmlkZS92b2QvP2FjPWRldGFpbCZpZHM9ZnlpZCcsCiAgICBzZWFyY2hVcmw6ICcvYXBpLnBocC9wcm92aWRlL3ZvZC8/d2Q9KiomcGc9I1RydWVQYWdlIyNwYWdlPWZ5cGFnZScsCiAgICBjbGFzc1VybDogJy9hcGkucGhwL3Byb3ZpZGUvdm9kLycsCiAgICB1cmw6ICcvYXBpLnBocC9wcm92aWRlL3ZvZC8/YWM9ZGV0YWlsJnBnPWZ5cGFnZSZ0PWZ5ZmlsdGVyJywKICAgIGZpbHRlcl91cmw6ICd7e2ZsLuexu+Wei319JywKICAgIGhlYWRlcnM6IHsnVXNlci1BZ2VudCc6ICdNT0JJTEVfVUEnfSwKICAgIHRpbWVvdXQ6IDUwMDAsIC8vIGNsYXNzX25hbWU6ICfnlLXlvbEm55S16KeG5YmnJue7vOiJuibliqjmvKsnLAogICAgbGltaXQ6IDIwLAogICAgc2VhcmNoX2xpbWl0OiA1LCAvLyDmkJzntKLpmZDliLblj5bliY015Liq77yM5Y+v5Lul5rOo6YeK5o6J77yM5bCx5LiN6ZmQ5Yi25pCc57SiCiAgICBzZWFyY2hhYmxlOiAxLC8v5piv5ZCm5ZCv55So5YWo5bGA5pCc57SiLAogICAgcXVpY2tTZWFyY2g6IDAsLy/mmK/lkKblkK/nlKjlv6vpgJ/mkJzntKIsCiAgICBmaWx0ZXJhYmxlOiAxLC8v5piv5ZCm5ZCv55So5YiG57G7562b6YCJLAogICAgcGxheV9wYXJzZTogdHJ1ZSwKICAgIHBhcnNlX3VybDogJycsIC8vIOi/meS4quWPguaVsOaaguaXtuS4jei1t+S9nOeUqOOAguiBmuWQiOexu+eahOavj+S4qui1hOa6kOW6lOivpeacieiHquW3seeLrOeri+eahOino+aekOWPo+OAguWNleeLrOmFjee9ruWcqOmHh+mbhi5qc29u6YeM55qEcGFyc2VfdXJs5pyJ5pWICiAgICBzZWFyY2hfbWF0Y2g6IGZhbHNlLCAvLyDmkJzntKLnsr7lh4bljLnphY0KICAgIHNlYXJjaF9waWM6IHRydWUsIC8vIOaQnOe0ouW8uuWItumcgOimgeWbvueJhwogICAgLy8gcGFyYW1zOiAnaHR0cDovLzEyNy4wLjAuMTo1NzA3L2ZpbGVzL2pzb24vJUU5JTg3JTg3JUU5JTlCJTg2Lmpzb24nLAogICAgLy8gcGFyYW1zOiAnaHR0cDovLzEyNy4wLjAuMTo1NzA3L2ZpbGVzL2pzb24v6YeH6ZuG6Z2Z5oCBLmpzb24kMScsCiAgICAvLyBwYXJhbXM6ICdodHRwOi8vMTI3LjAuMC4xOjU3MDcvZmlsZXMvanNvbi/ph4fpm4Zbenld6Z2Z5oCBLmpzb24kMScsCiAgICAvLyBob3N0SnM6JGpzLnRvU3RyaW5nKCgpPT57CiAgICAvLwogICAgLy8gfSksCiAgICDpooTlpITnkIY6ICRqcy50b1N0cmluZygoKSA9PiB7CiAgICAgICAgZnVuY3Rpb24gZ2V0Q2xhc3NlcyhpdGVtKSB7CiAgICAgICAgICAgIGxldCBjbGFzc2VzID0gW107CiAgICAgICAgICAgIGlmIChpdGVtLmNsYXNzX25hbWUgJiYgaXRlbS5jbGFzc191cmwpIHsKICAgICAgICAgICAgICAgIGlmICghLyZ855S15b2xfOeUteinhuWJp3znu7zoibp85Yqo5ryrW1x1NEUwMC1cdTlGQTVdKy8udGVzdChpdGVtLmNsYXNzX25hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5jbGFzc19uYW1lID0gdW5nemlwKGl0ZW0uY2xhc3NfbmFtZSkKICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhg5LiN6K+G5Yir55qEY2xhc3NfbmFtZeWvvOiHtGd6aXDop6PnoIHlpLHotKU6JHtlfWApCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbGFzc2VzCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbGV0IG5hbWVzID0gaXRlbS5jbGFzc19uYW1lLnNwbGl0KCcmJyk7CiAgICAgICAgICAgICAgICBsZXQgdXJscyA9IGl0ZW0uY2xhc3NfdXJsLnNwbGl0KCcmJyk7CiAgICAgICAgICAgICAgICBsZXQgY250ID0gTWF0aC5taW4obmFtZXMubGVuZ3RoLCB1cmxzLmxlbmd0aCk7CiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNudDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgJ3R5cGVfaWQnOiB1cmxzW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAndHlwZV9uYW1lJzogbmFtZXNbaV0KICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY2xhc3NlcwogICAgICAgIH0KCiAgICAgICAgaWYgKHR5cGVvZiAoYmF0Y2hGZXRjaCkgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgLy8g5pSv5oyB5om56YeP6K+35rGC55u05o6l5pS+6aOe6Ieq5oiR44CC5pCc57Si6ZmQ5Yi25pyA5aSn57q/56iL5pWw6YePMTYKICAgICAgICAgICAgcnVsZS5zZWFyY2hfbGltaXQgPSAxNjsKICAgICAgICAgICAgbG9nKCflvZPliY3nqIvluo/mlK/mjIHmibnph4/or7fmsYJbYmF0Y2hGZXRjaF0s5pCc57Si6ZmQ5Yi25bey6K6+572u5Li6MTYnKTsKICAgICAgICB9CiAgICAgICAgbGV0IF91cmwgPSBydWxlLnBhcmFtczsKICAgICAgICBsb2coYOS8oOWFpeWPguaVsDoke191cmx9YCk7CiAgICAgICAgaWYgKF91cmwgJiYgdHlwZW9mIChfdXJsKSA9PT0gJ3N0cmluZycgJiYgL14oaHR0cHxmaWxlKS8udGVzdChfdXJsKSkgewogICAgICAgICAgICBpZiAoX3VybC5pbmNsdWRlcygnJCcpKSB7CiAgICAgICAgICAgICAgICBsZXQgX3VybF9wYXJhbXMgPSBfdXJsLnNwbGl0KCckJyk7CiAgICAgICAgICAgICAgICBfdXJsID0gX3VybF9wYXJhbXNbMF07CiAgICAgICAgICAgICAgICBydWxlLnNlYXJjaF9tYXRjaCA9ICEhKF91cmxfcGFyYW1zWzFdKTsKICAgICAgICAgICAgICAgIGlmIChfdXJsX3BhcmFtcy5sZW5ndGggPiAyKSB7IC8vIOW8uuWItuWbvueJhwogICAgICAgICAgICAgICAgICAgIHJ1bGUuc2VhcmNoX3BpYyA9ICEhKF91cmxfcGFyYW1zWzJdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgaHRtbCA9IHJlcXVlc3QoX3VybCk7CiAgICAgICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShodG1sKTsKICAgICAgICAgICAgbGV0IF9jbGFzc2VzID0gW107CiAgICAgICAgICAgIHJ1bGUuZmlsdGVyID0ge307CiAgICAgICAgICAgIHJ1bGUuZmlsdGVyX2RlZiA9IHt9OwogICAgICAgICAgICBqc29uLmZvckVhY2goaXQgPT4gewogICAgICAgICAgICAgICAgbGV0IF9vYmogPSB7CiAgICAgICAgICAgICAgICAgICAgdHlwZV9uYW1lOiBpdC5uYW1lLAogICAgICAgICAgICAgICAgICAgIHR5cGVfaWQ6IGl0LnVybCwKICAgICAgICAgICAgICAgICAgICBwYXJzZV91cmw6IGl0LnBhcnNlX3VybCB8fCAnJywKICAgICAgICAgICAgICAgICAgICBzZWFyY2hhYmxlOiBpdC5zZWFyY2hhYmxlICE9PSAwLAogICAgICAgICAgICAgICAgICAgIGFwaTogaXQuYXBpIHx8ICcnLAogICAgICAgICAgICAgICAgICAgIGNhdGVfZXhjbHVkZTogaXQuY2F0ZV9leGNsdWRlIHx8ICcnLAogICAgICAgICAgICAgICAgICAgIGNhdGVfZXhjbHVkZXM6IGl0LmNhdGVfZXhjbHVkZXMgfHwgW10sCiAgICAgICAgICAgICAgICAgICAgLy8gY2xhc3NfbmFtZTogaXQuY2xhc3NfbmFtZSB8fCAnJywKICAgICAgICAgICAgICAgICAgICAvLyBjbGFzc191cmw6IGl0LmNsYXNzX3VybCB8fCAnJywKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBfY2xhc3Nlcy5wdXNoKF9vYmopOwogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICBsZXQganNvbjEgPSBbXTsKICAgICAgICAgICAgICAgICAgICBpZiAoaXQuY2xhc3NfbmFtZSAmJiBpdC5jbGFzc191cmwpIHsKICAgICAgICAgICAgICAgICAgICAgICAganNvbjEgPSBnZXRDbGFzc2VzKGl0KTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBqc29uMSA9IEpTT04ucGFyc2UocmVxdWVzdCh1cmxqb2luKF9vYmoudHlwZV9pZCwgX29iai5hcGkgfHwgcnVsZS5jbGFzc1VybCkpKS5jbGFzczsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKF9vYmouY2F0ZV9leGNsdWRlcyAmJiBBcnJheS5pc0FycmF5KF9vYmouY2F0ZV9leGNsdWRlcykgJiYgX29iai5jYXRlX2V4Y2x1ZGVzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAganNvbjEgPSBqc29uMS5maWx0ZXIoY2wgPT4gIV9vYmouY2F0ZV9leGNsdWRlcy5pbmNsdWRlcyhjbC50eXBlX25hbWUpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKF9vYmouY2F0ZV9leGNsdWRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGpzb24xID0ganNvbjEuZmlsdGVyKGNsID0+ICFuZXcgUmVnRXhwKF9vYmouY2F0ZV9leGNsdWRlLCAnaScpLnRlc3QoY2wudHlwZV9uYW1lKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJ1bGUuZmlsdGVyW19vYmoudHlwZV9pZF0gPSBbewogICAgICAgICAgICAgICAgICAgICAgICAia2V5IjogIuexu+WeiyIsICJuYW1lIjogIuexu+WeiyIsICJ2YWx1ZSI6IGpzb24xLm1hcChpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7Im4iOiBpLnR5cGVfbmFtZSwgJ3YnOiBpLnR5cGVfaWR9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICAgICAgfV07CiAgICAgICAgICAgICAgICAgICAgaWYgKGpzb24xLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcnVsZS5maWx0ZXJfZGVmW2l0LnVybF0gPSB7Iuexu+WeiyI6IGpzb24xWzBdLnR5cGVfaWR9OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICBydWxlLmZpbHRlcltpdC51cmxdID0gW3sia2V5IjogIuexu+WeiyIsICJuYW1lIjogIuexu+WeiyIsICJ2YWx1ZSI6IFt7Im4iOiAi5YWo6YOoIiwgInYiOiAiIn1dfV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBydWxlLmNsYXNzZXMgPSBfY2xhc3NlczsKICAgICAgICB9CiAgICB9KSwKICAgIC8vIGNsYXNzX3BhcnNlOiAkanMudG9TdHJpbmcoKCkgPT4gewogICAgLy8gICAgIGxldCBfdXJsID0gcnVsZS5wYXJhbXM7CiAgICAvLyAgICAgaWYgKF91cmwgJiYgdHlwZW9mIChfdXJsKSA9PT0gJ3N0cmluZycgJiYgX3VybC5zdGFydHNXaXRoKCdodHRwJykpIHsKICAgIC8vICAgICAgICAgbGV0IGh0bWwgPSByZXF1ZXN0KF91cmwpOwogICAgLy8gICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAvLyAgICAgICAgIGxldCBfY2xhc3NlcyA9IFtdOwogICAgLy8gICAgICAgICBob21lT2JqLmZpbHRlciA9IHt9OwogICAgLy8gICAgICAgICBydWxlLmZpbHRlcl9kZWYgPSB7fTsKICAgIC8vICAgICAgICAganNvbi5mb3JFYWNoKGl0ID0+IHsKICAgIC8vICAgICAgICAgICAgIGxldCBfb2JqID0gewogICAgLy8gICAgICAgICAgICAgICAgIHR5cGVfbmFtZTogaXQubmFtZSwKICAgIC8vICAgICAgICAgICAgICAgICB0eXBlX2lkOiBpdC51cmwsCiAgICAvLyAgICAgICAgICAgICAgICAgcGFyc2VfdXJsOiBpdC5wYXJzZV91cmwgfHwgJycsCiAgICAvLyAgICAgICAgICAgICAgICAgY2F0ZV9leGNsdWRlOiBpdC5jYXRlX2V4Y2x1ZGUgfHwgJycsCiAgICAvLyAgICAgICAgICAgICB9OwogICAgLy8gICAgICAgICAgICAgX2NsYXNzZXMucHVzaChfb2JqKTsKICAgIC8vICAgICAgICAgICAgIHRyeSB7CiAgICAvLyAgICAgICAgICAgICAgICAgbGV0IGpzb24xID0gSlNPTi5wYXJzZShyZXF1ZXN0KHVybGpvaW4oX29iai50eXBlX2lkLCBydWxlLmNsYXNzVXJsKSkpLmNsYXNzOwogICAgLy8gICAgICAgICAgICAgICAgIGlmIChfb2JqLmNhdGVfZXhjbHVkZSkgewogICAgLy8gICAgICAgICAgICAgICAgICAgICBqc29uMSA9IGpzb24xLmZpbHRlcihjbCA9PiAhbmV3IFJlZ0V4cChfb2JqLmNhdGVfZXhjbHVkZSwgJ2knKS50ZXN0KGNsLnR5cGVfbmFtZSkpOwogICAgLy8gICAgICAgICAgICAgICAgIH0KICAgIC8vICAgICAgICAgICAgICAgICBob21lT2JqLmZpbHRlcltfb2JqLnR5cGVfaWRdID0gW3sKICAgIC8vICAgICAgICAgICAgICAgICAgICAgImtleSI6ICLnsbvlnosiLCAibmFtZSI6ICLnsbvlnosiLCAidmFsdWUiOiBqc29uMS5tYXAoaSA9PiB7CiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyJuIjogaS50eXBlX25hbWUsICd2JzogaS50eXBlX2lkfQogICAgLy8gICAgICAgICAgICAgICAgICAgICB9KQogICAgLy8gICAgICAgICAgICAgICAgIH1dOwogICAgLy8gICAgICAgICAgICAgICAgIGlmIChqc29uMS5sZW5ndGggPiAwKSB7CiAgICAvLyAgICAgICAgICAgICAgICAgICAgIHJ1bGUuZmlsdGVyX2RlZltpdC51cmxdID0geyLnsbvlnosiOiBqc29uMVswXS50eXBlX2lkfTsKICAgIC8vICAgICAgICAgICAgICAgICB9CiAgICAvLyAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAvLyAgICAgICAgICAgICAgICAgaG9tZU9iai5maWx0ZXJbaXQudXJsXSA9IFt7ImtleSI6ICLnsbvlnosiLCAibmFtZSI6ICLnsbvlnosiLCAidmFsdWUiOiBbeyJuIjogIuWFqOmDqCIsICJ2IjogIiJ9XX1dOwogICAgLy8gICAgICAgICAgICAgfQogICAgLy8gICAgICAgICB9KTsKICAgIC8vICAgICAgICAgcnVsZS5jbGFzc2VzID0gX2NsYXNzZXM7CiAgICAvLyAgICAgICAgIGlucHV0ID0gX2NsYXNzZXM7CiAgICAvLyAgICAgfQogICAgLy8gfSksCiAgICBjbGFzc19wYXJzZTogJGpzLnRvU3RyaW5nKCgpID0+IHsKICAgICAgICBpbnB1dCA9IHJ1bGUuY2xhc3NlczsKICAgIH0pLAogICAg5o6o6I2QOiAkanMudG9TdHJpbmcoKCkgPT4gewogICAgICAgIGxldCB1cGRhdGVfaW5mbyA9IFt7CiAgICAgICAgICAgIHZvZF9uYW1lOiAn5pu05paw5pel5b+XJywKICAgICAgICAgICAgdm9kX2lkOiAndXBkYXRlX2luZm8nLAogICAgICAgICAgICB2b2RfcmVtYXJrczogYOeJiOacrDoke3J1bGUudmVyc2lvbn1gLAogICAgICAgICAgICB2b2RfcGljOiAnaHR0cHM6Ly9naHByb3h5Lm5ldC9odHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vaGpkaG54L2hpcHktc2VydmVyL21hc3Rlci9hcHAvc3RhdGljL2ltZy9sb2dvLnBuZycKICAgICAgICB9XTsKICAgICAgICBWT0RTID0gW107CiAgICAgICAgaWYgKHJ1bGUuY2xhc3NlcykgewogICAgICAgICAgICBsZXQgcmFuZG9tQ2xhc3MgPSBnZXRSYW5kb21JdGVtKHJ1bGUuY2xhc3Nlcyk7CiAgICAgICAgICAgIGxldCBfdXJsID0gdXJsam9pbihyYW5kb21DbGFzcy50eXBlX2lkLCBpbnB1dCk7CiAgICAgICAgICAgIGlmIChyYW5kb21DbGFzcy5hcGkpIHsKICAgICAgICAgICAgICAgIF91cmwgPSBfdXJsLnJlcGxhY2UoJy9hcGkucGhwL3Byb3ZpZGUvdm9kLycsIHJhbmRvbUNsYXNzLmFwaSkKICAgICAgICAgICAgfQogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgbGV0IGh0bWwgPSByZXF1ZXN0KF91cmwsIHt0aW1lb3V0OiBydWxlLnRpbWVvdXR9KTsKICAgICAgICAgICAgICAgIGxldCBqc29uID0gSlNPTi5wYXJzZShodG1sKTsKICAgICAgICAgICAgICAgIFZPRFMgPSBqc29uLmxpc3Q7CiAgICAgICAgICAgICAgICBWT0RTLmZvckVhY2goaXQgPT4gewogICAgICAgICAgICAgICAgICAgIGl0LnZvZF9pZCA9IHJhbmRvbUNsYXNzLnR5cGVfaWQgKyAnJCcgKyBpdC52b2RfaWQ7CiAgICAgICAgICAgICAgICAgICAgaXQudm9kX3JlbWFya3MgPSBpdC52b2RfcmVtYXJrcyArICd8JyArIHJhbmRvbUNsYXNzLnR5cGVfbmFtZTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVk9EUyA9IHVwZGF0ZV9pbmZvLmNvbmNhdChWT0RTKTsKICAgIH0pLAogICAg5LiA57qnOiAkanMudG9TdHJpbmcoKCkgPT4gewogICAgICAgIFZPRFMgPSBbXTsKICAgICAgICBpZiAocnVsZS5jbGFzc2VzKSB7CiAgICAgICAgICAgIC8vIGxvZyhpbnB1dCk7CiAgICAgICAgICAgIGxldCBfdXJsID0gdXJsam9pbihNWV9DQVRFLCBpbnB1dCk7CiAgICAgICAgICAgIGxldCBjdXJyZW50X3ZvZCA9IHJ1bGUuY2xhc3Nlcy5maW5kKGl0ZW0gPT4gaXRlbS50eXBlX2lkID09PSBNWV9DQVRFKTsKICAgICAgICAgICAgaWYgKGN1cnJlbnRfdm9kICYmIGN1cnJlbnRfdm9kLmFwaSkgewogICAgICAgICAgICAgICAgX3VybCA9IF91cmwucmVwbGFjZSgnL2FwaS5waHAvcHJvdmlkZS92b2QvJywgY3VycmVudF92b2QuYXBpKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGxldCBodG1sID0gcmVxdWVzdChfdXJsKTsKICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKGh0bWwpOwogICAgICAgICAgICBWT0RTID0ganNvbi5saXN0OwogICAgICAgICAgICBWT0RTLmZvckVhY2goaXQgPT4gewogICAgICAgICAgICAgICAgaXQudm9kX2lkID0gTVlfQ0FURSArICckJyArIGl0LnZvZF9pZAogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9KSwKICAgIC8vIOS4gOe6pzogJ2pzb246bGlzdDt2b2RfbmFtZTt2b2RfcGljO3ZvZF9yZW1hcmtzO3ZvZF9pZDt2b2RfcGxheV9mcm9tJywKICAgIOS6jOe6pzogJGpzLnRvU3RyaW5nKCgpID0+IHsKICAgICAgICBWT0QgPSB7fTsKICAgICAgICBpZiAob3JJZCA9PT0gJ3VwZGF0ZV9pbmZvJykgewogICAgICAgICAgICBWT0QgPSB7CiAgICAgICAgICAgICAgICB2b2RfY29udGVudDogcnVsZS51cGRhdGVfaW5mby50cmltKCksCiAgICAgICAgICAgICAgICB2b2RfbmFtZTogJ+abtOaWsOaXpeW/lycsCiAgICAgICAgICAgICAgICB0eXBlX25hbWU6ICfmm7TmlrDml6Xlv5cnLAogICAgICAgICAgICAgICAgdm9kX3BpYzogJ2h0dHBzOi8vcmVzb3VyY2UtY2RuLnR1eGlhb2JlaS5jb20vdmlkZW8vRnRXaHMybWV3WF83bkV1RTUxX2s2enZnNmF3bC5wbmcnLAogICAgICAgICAgICAgICAgdm9kX3JlbWFya3M6IGDniYjmnKw6JHtydWxlLnZlcnNpb259YCwKICAgICAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfpgZPplb/lnKjnur8nLAogICAgICAgICAgICAgICAgLy8gdm9kX3BsYXlfdXJsOiAn5ZeF5o6i5pKt5pS+JGh0dHBzOi8vcmVzb3VyY2UtY2RuLnR1eGlhb2JlaS5jb20vdmlkZW8vMTAvOGYvMTA4ZmM5ZDFhYzNmNjlkMjlhNzM4Y2RjMDk3YzkwMTgubXA0JywKICAgICAgICAgICAgICAgIHZvZF9wbGF5X3VybDogJ+maj+acuuWwj+inhumikSRodHRwOi8vYXBpLnl1am4uY24vYXBpL3p6eGpqLnBocCcsCiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKHJ1bGUuY2xhc3NlcykgewogICAgICAgICAgICAgICAgbGV0IF91cmwgPSB1cmxqb2luKGZ5Y2xhc3MsIGlucHV0KTsKICAgICAgICAgICAgICAgIGxldCBjdXJyZW50X3ZvZCA9IHJ1bGUuY2xhc3Nlcy5maW5kKGl0ZW0gPT4gaXRlbS50eXBlX2lkID09PSBmeWNsYXNzKTsKICAgICAgICAgICAgICAgIGlmIChjdXJyZW50X3ZvZCAmJiBjdXJyZW50X3ZvZC5hcGkpIHsKICAgICAgICAgICAgICAgICAgICBfdXJsID0gX3VybC5yZXBsYWNlKCcvYXBpLnBocC9wcm92aWRlL3ZvZC8nLCBjdXJyZW50X3ZvZC5hcGkpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsZXQgaHRtbCA9IHJlcXVlc3QoX3VybCk7CiAgICAgICAgICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IGpzb24ubGlzdDsKICAgICAgICAgICAgICAgIFZPRCA9IGRhdGFbMF07CiAgICAgICAgICAgICAgICBpZiAoY3VycmVudF92b2QgJiYgY3VycmVudF92b2QudHlwZV9uYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgVk9ELnZvZF9wbGF5X2Zyb20gPSBWT0Qudm9kX3BsYXlfZnJvbS5zcGxpdCgnJCQkJykubWFwKGl0ID0+IGN1cnJlbnRfdm9kLnR5cGVfbmFtZSArICd8JyArIGl0KS5qb2luKCckJCQnKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSksCiAgICDmkJzntKI6ICRqcy50b1N0cmluZygoKSA9PiB7CiAgICAgICAgVk9EUyA9IFtdOwogICAgICAgIGlmIChydWxlLmNsYXNzZXMpIHsKICAgICAgICAgICAgbGV0IGNhblNlYXJjaCA9IHJ1bGUuY2xhc3Nlcy5maWx0ZXIoaXQgPT4gaXQuc2VhcmNoYWJsZSk7CiAgICAgICAgICAgIGxldCBwYWdlID0gTnVtYmVyKE1ZX1BBR0UpOwogICAgICAgICAgICBwYWdlID0gKE1ZX1BBR0UgLSAxKSAlIE1hdGguY2VpbChjYW5TZWFyY2gubGVuZ3RoIC8gcnVsZS5zZWFyY2hfbGltaXQpICsgMTsKICAgICAgICAgICAgbGV0IHRydWVQYWdlID0gTWF0aC5jZWlsKE1ZX1BBR0UgLyBNYXRoLmNlaWwoY2FuU2VhcmNoLmxlbmd0aCAvIHJ1bGUuc2VhcmNoX2xpbWl0KSk7CiAgICAgICAgICAgIGlmIChydWxlLnNlYXJjaF9saW1pdCkgewogICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gKHBhZ2UgLSAxKSAqIHJ1bGUuc2VhcmNoX2xpbWl0OwogICAgICAgICAgICAgICAgbGV0IGVuZCA9IHBhZ2UgKiBydWxlLnNlYXJjaF9saW1pdDsKICAgICAgICAgICAgICAgIGxldCB0MSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwogICAgICAgICAgICAgICAgbGV0IHNlYXJjaE1vZGUgPSB0eXBlb2YgKGJhdGNoRmV0Y2gpID09PSAnZnVuY3Rpb24nID8gJ+aJuemHjycgOiAn5Y2V5LiqJzsKICAgICAgICAgICAgICAgIGxvZygnc3RhcnQ6JyArIHN0YXJ0KTsKICAgICAgICAgICAgICAgIGxvZygnZW5kOicgKyBlbmQpOwogICAgICAgICAgICAgICAgbG9nKCfmkJzntKLmqKHlvI86JyArIHNlYXJjaE1vZGUpOwogICAgICAgICAgICAgICAgbG9nKCfnsr7lh4bmkJzntKI6JyArIHJ1bGUuc2VhcmNoX21hdGNoKTsKICAgICAgICAgICAgICAgIC8vIGxvZygndDE6JyArIHQxKTsKICAgICAgICAgICAgICAgIGlmIChzdGFydCA8IGNhblNlYXJjaC5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICBsZXQgc2VhcmNoX2NsYXNzZXMgPSBjYW5TZWFyY2guc2xpY2Uoc3RhcnQsIGVuZCk7CiAgICAgICAgICAgICAgICAgICAgbGV0IHVybHMgPSBbXTsKICAgICAgICAgICAgICAgICAgICBzZWFyY2hfY2xhc3Nlcy5mb3JFYWNoKGl0ID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgbGV0IF91cmwgPSB1cmxqb2luKGl0LnR5cGVfaWQsIGlucHV0KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0LmFwaSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3VybCA9IF91cmwucmVwbGFjZSgnL2FwaS5waHAvcHJvdmlkZS92b2QvJywgaXQuYXBpKQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIF91cmwgPSBfdXJsLnJlcGxhY2UoIiNUcnVlUGFnZSMiLCAiIiArIHRydWVQYWdlKTsKICAgICAgICAgICAgICAgICAgICAgICAgdXJscy5wdXNoKF91cmwpOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIGxldCByZXN1bHRzX2xpc3QgPSBbXTsKICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0cyA9IFtdOwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgKGJhdGNoRmV0Y2gpID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXFVcmxzID0gdXJscy5tYXAoaXQgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cmw6IGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHt0aW1lb3V0OiBydWxlLnRpbWVvdXR9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmV0cyA9IGJhdGNoRmV0Y2gocmVxVXJscyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkZXRhaWxVcmxzID0gW107CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkZXRhaWxVcmxDb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHMuZm9yRWFjaCgocmV0LCBpZHgpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpdCA9IHNlYXJjaF9jbGFzc2VzW2lkeF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmV0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlKHJldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkYXRhID0ganNvbi5saXN0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmZvckVhY2goaSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLnNpdGVfbmFtZSA9IGl0LnR5cGVfbmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkudm9kX2lkID0gaXQudHlwZV9pZCArICckJyArIGkudm9kX2lkOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaS52b2RfcmVtYXJrcyA9IGkudm9kX3JlbWFya3MgKyAnfCcgKyBpdC50eXBlX25hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocnVsZS5zZWFyY2hfbWF0Y2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLmZpbHRlcihpdGVtID0+IGl0ZW0udm9kX25hbWUgJiYgKG5ldyBSZWdFeHAoS0VZLCAnaScpKS50ZXN0KGl0ZW0udm9kX25hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlLnNlYXJjaF9waWMgJiYgIWRhdGFbMF0udm9kX3BpYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhg5b2T5YmN5pCc57Si56uZ54K544CQJHtpdC50eXBlX25hbWV944CR5rKh5Zu+54mHLOWwneivleiuv+mXruS6jOe6p+WOu+iOt+WPluWbvueJh2ApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkZXRhaWxVcmwgPSB1cmxzW2lkeF0uc3BsaXQoJ3dkPScpWzBdICsgJ2FjPWRldGFpbCZpZHM9JyArIGRhdGEubWFwKGsgPT4gay52b2RfaWQuc3BsaXQoJyQnKVsxXSkuam9pbignLCcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldGFpbFVybHMucHVzaChkZXRhaWxVcmwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNfbGlzdC5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzX3BpYzogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldGFpbFVybENvdW50OiBkZXRhaWxVcmxDb3VudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldGFpbFVybENvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgbGV0IGRldGFpbEpzb24gPSBKU09OLnBhcnNlKHJlcXVlc3QoZGV0YWlsVXJsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGRhdGEuZm9yRWFjaCgoZCwgX3NlcSkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgbG9nKCfkuoznuqfmlbDmja7liJfooajlhYPntKDmlbA6JyArIGRldGFpbEpzb24ubGlzdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgbGV0IGRldGFpbFZvZFBpYyA9IGRldGFpbEpzb24ubGlzdFtfc2VxXS52b2RfcGljOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgaWYgKGRldGFpbFZvZFBpYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oZCwge3ZvZF9waWM6IGRldGFpbFZvZFBpY30pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGxvZyhg5by65Yi26I635Y+W572R56uZJHtpdC50eXBlX2lkfeeahOaQnOe0ouWbvueJh+Wksei0pToke2UubWVzc2FnZX1gKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNfbGlzdC5wdXNoKHtkYXRhOiBkYXRhLCBoYXNfcGljOiB0cnVlfSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzdWx0cyA9IHJlc3VsdHMuY29uY2F0KGRhdGEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coYOivt+axgjoke2l0LnR5cGVfaWR95Y+R55Sf6ZSZ6K+vOiR7ZS5tZXNzYWdlfWApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgLy8g5p6E6YCg6K+35rGC5LqM57qn55qEYmF0Y2hGZXRjaOWIl+ihqAogICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmVxVXJsczIgPSBkZXRhaWxVcmxzLm1hcChpdCA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVybDogaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczoge3RpbWVvdXQ6IHJ1bGUudGltZW91dH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXRzMiA9IGJhdGNoRmV0Y2gocmVxVXJsczIpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHJlc3VsdHNfbGlzdC5sZW5ndGg7IGsrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3VsdF9kYXRhID0gcmVzdWx0c19saXN0W2tdLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdHNfbGlzdFtrXS5oYXNfcGljKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRldGFpbEpzb24gPSBKU09OLnBhcnNlKHJldHMyW3Jlc3VsdHNfbGlzdFtrXS5kZXRhaWxVcmxDb3VudF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coJ+S6jOe6p+aVsOaNruWIl+ihqOWFg+e0oOaVsDonICsgZGV0YWlsSnNvbi5saXN0Lmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdF9kYXRhLmZvckVhY2goKGQsIF9zZXEpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxldCBkZXRhaWxWb2RQaWMgPSBkZXRhaWxKc29uLmxpc3RbX3NlcV0udm9kX3BpYzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvZyhkZXRhaWxKc29uKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkZXRhaWxWb2RQaWMgPSBkZXRhaWxKc29uLmxpc3QuZmluZCh2b2QgPT4gdm9kLnZvZF9pZC50b1N0cmluZygpID09PSBkLnZvZF9pZC5zcGxpdCgnJCcpWzFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXRhaWxWb2RQaWMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKGQsIHt2b2RfcGljOiBkZXRhaWxWb2RQaWMudm9kX3BpY30pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhg5by65Yi26I635Y+W572R56uZJHtyZXN1bHRfZGF0YVswXS5zaXRlX25hbWV955qE5pCc57Si5Zu+54mH5aSx6LSlOiR7ZS5tZXNzYWdlfWApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChyZXN1bHRfZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdXJscy5mb3JFYWNoKChfdXJsLCBpZHgpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpdCA9IHNlYXJjaF9jbGFzc2VzW2lkeF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBodG1sID0gcmVxdWVzdChfdXJsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQganNvbiA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRhdGEgPSBqc29uLmxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKGkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLnZvZF9pZCA9IGl0LnR5cGVfaWQgKyAnJCcgKyBpLnZvZF9pZDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaS52b2RfcmVtYXJrcyA9IGkudm9kX3JlbWFya3MgKyAnfCcgKyBpdC50eXBlX25hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuc2VhcmNoX21hdGNoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLmZpbHRlcihpdGVtID0+IGl0ZW0udm9kX25hbWUgJiYgKG5ldyBSZWdFeHAoS0VZLCAnaScpKS50ZXN0KGl0ZW0udm9kX25hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlLnNlYXJjaF9waWMgJiYgIWRhdGFbMF0udm9kX3BpYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKGDlvZPliY3mkJzntKLnq5nngrnjgJAke2l0LnR5cGVfbmFtZX3jgJHmsqHlm77niYcs5bCd6K+V6K6/6Zeu5LqM57qn5Y676I635Y+W5Zu+54mHYCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGV0YWlsVXJsID0gdXJsc1tpZHhdLnNwbGl0KCd3ZD0nKVswXSArICdhYz1kZXRhaWwmaWRzPScgKyBkYXRhLm1hcChrID0+IGsudm9kX2lkLnNwbGl0KCckJylbMV0pLmpvaW4oJywnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRldGFpbEpzb24gPSBKU09OLnBhcnNlKHJlcXVlc3QoZGV0YWlsVXJsKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nKCfkuoznuqfmlbDmja7liJfooajlhYPntKDmlbA6JyArIGRldGFpbEpzb24ubGlzdC5sZW5ndGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuZm9yRWFjaCgoZCwgX3NlcSkgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBsZXQgZGV0YWlsVm9kUGljID0gZGV0YWlsSnNvbi5saXN0W19zZXFdLnZvZF9waWM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkZXRhaWxWb2RQaWMgPSBkZXRhaWxKc29uLmxpc3QuZmluZCh2b2QgPT4gdm9kLnZvZF9pZC50b1N0cmluZygpID09PSBkLnZvZF9pZC5zcGxpdCgnJCcpWzFdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRldGFpbFZvZFBpYykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihkLCB7dm9kX3BpYzogZGV0YWlsVm9kUGljLnZvZF9waWN9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZyhg5by65Yi26I635Y+W572R56uZJHtpdC50eXBlX2lkfeeahOaQnOe0ouWbvueJh+Wksei0pToke2UubWVzc2FnZX1gKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5jb25jYXQoZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChkYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2coYOivt+axgjoke2l0LnR5cGVfaWR95Y+R55Sf6ZSZ6K+vOiR7ZS5tZXNzYWdlfWApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgVk9EUyA9IHJlc3VsdHM7CiAgICAgICAgICAgICAgICAgICAgbGV0IHQyID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7CiAgICAgICAgICAgICAgICAgICAgLy8gbG9nKCd0MjonK3QyKTsKICAgICAgICAgICAgICAgICAgICBsb2coYCR7c2VhcmNoTW9kZX3mkJzntKI6JHt1cmxzLmxlbmd0aH3kuKrnq5nogJfml7Y6JHsoTnVtYmVyKHQyKSAtIE51bWJlcih0MSkpfW1zYCkKCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9KSwKICAgIGxhenk6ICRqcy50b1N0cmluZygoKSA9PiB7CiAgICAgICAgLy8gbGF6eeaDs+WKnuazleeUqOWvueW6lOeahHBhcnNlX3VybO+8jOS9huaYr+aciemavuW6pu+8jOaaguacquWunueOsAogICAgICAgIGxldCBwYXJzZV91cmwgPSAnJzsKICAgICAgICBpZiAoZmxhZyAmJiBmbGFnLmluY2x1ZGVzKCd8JykpIHsKICAgICAgICAgICAgbGV0IHR5cGVfbmFtZSA9IGZsYWcuc3BsaXQoJ3wnKVswXTsKICAgICAgICAgICAgbGV0IGN1cnJlbnRfdm9kID0gcnVsZS5jbGFzc2VzLmZpbmQoaXRlbSA9PiBpdGVtLnR5cGVfbmFtZSA9PT0gdHlwZV9uYW1lKTsKICAgICAgICAgICAgaWYgKGN1cnJlbnRfdm9kICYmIGN1cnJlbnRfdm9kLnBhcnNlX3VybCkgewogICAgICAgICAgICAgICAgcGFyc2VfdXJsID0gY3VycmVudF92b2QucGFyc2VfdXJsCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKC9cLihtM3U4fG1wNCkvLnRlc3QoaW5wdXQpKSB7CiAgICAgICAgICAgIGlucHV0ID0ge3BhcnNlOiAwLCB1cmw6IGlucHV0fQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChwYXJzZV91cmwuc3RhcnRzV2l0aCgnanNvbjonKSkgewogICAgICAgICAgICAgICAgbGV0IHB1cmwgPSBwYXJzZV91cmwucmVwbGFjZSgnanNvbjonLCAnJykgKyBpbnB1dDsKICAgICAgICAgICAgICAgIGxldCBodG1sID0gcmVxdWVzdChwdXJsKTsKICAgICAgICAgICAgICAgIGlucHV0ID0ge3BhcnNlOiAwLCB1cmw6IEpTT04ucGFyc2UoaHRtbCkudXJsfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaW5wdXQgPSBwYXJzZV91cmwgKyBpbnB1dDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0pLAp9
|
||||
Reference in New Issue
Block a user