mirror of
https://gitlab.com/SukkaW/ruleset.skk.moe.git
synced 2026-01-09 05:50:27 +00:00
deploy: 521cc9020218e7b930a9bb873cabced01b877579
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
const { fetchWithRetry } = require('./lib/fetch-retry');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { isIP } = require('net');
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-anti-bogus-domain');
|
||||
console.time('* Download bogus-nxdomain-list')
|
||||
const res = (await (await fetchWithRetry('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf')).text())
|
||||
.split('\n')
|
||||
.map(line => {
|
||||
if (line.startsWith('bogus-nxdomain=')) {
|
||||
return line.replace('bogus-nxdomain=', '');
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
.filter(ip => typeof ip === 'string' && isIP(ip) !== 0);
|
||||
console.timeEnd('* Download bogus-nxdomain-list')
|
||||
|
||||
const filePath = path.resolve(__dirname, '../List/ip/reject.conf');
|
||||
const content = (await fs.promises.readFile(filePath, 'utf-8'))
|
||||
.replace(
|
||||
'# --- [Anti Bogus Domain Replace Me] ---',
|
||||
res.map(ip => `IP-CIDR,${ip}/32,no-resolve`).join('\n')
|
||||
);
|
||||
|
||||
await fs.promises.writeFile(filePath, content, 'utf-8');
|
||||
console.timeEnd('Total Time - build-anti-bogus-domain');
|
||||
})();
|
||||
@@ -1,35 +0,0 @@
|
||||
const { fetchWithRetry } = require('./lib/fetch-retry');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const rDomain = /^(((?!\-))(xn\-\-)?[a-z0-9\-_]{0,61}[a-z0-9]{1,1}\.)*(xn\-\-)?([a-z0-9\-]{1,61}|[a-z0-9\-]{1,30})\.[a-z]{2,}$/m;
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-apple-cdn-conf');
|
||||
|
||||
const res = (await (await fetchWithRetry('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf')).text())
|
||||
.split('\n')
|
||||
.map(line => {
|
||||
if (line.startsWith('server=/') && line.endsWith('/114.114.114.114')) {
|
||||
return line.replace('server=/', '').replace('/114.114.114.114', '');
|
||||
}
|
||||
|
||||
return null
|
||||
})
|
||||
.filter(domain => typeof domain === 'string' && rDomain.test(domain));
|
||||
|
||||
await Promise.all([
|
||||
fs.promises.writeFile(
|
||||
path.resolve(__dirname, '../List/non_ip/apple_cdn.conf'),
|
||||
res.map(domain => `DOMAIN-SUFFIX,${domain}`).join('\n') + '\n',
|
||||
'utf-8'
|
||||
),
|
||||
fs.promises.writeFile(
|
||||
path.resolve(__dirname, '../List/domainset/apple_cdn.conf'),
|
||||
res.map(i => `.${i}`).join('\n') + '\n',
|
||||
'utf-8'
|
||||
)
|
||||
])
|
||||
|
||||
console.timeEnd('Total Time - build-apple-cdn-conf');
|
||||
})();
|
||||
@@ -1,36 +0,0 @@
|
||||
const { fetchWithRetry } = require('./lib/fetch-retry');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-cdn-conf');
|
||||
|
||||
const domains = (await (await fetchWithRetry('https://publicsuffix.org/list/public_suffix_list.dat')).text()).split('\n');
|
||||
|
||||
const S3OSSDomains = domains.filter(line => {
|
||||
if (line) {
|
||||
return (
|
||||
line.startsWith('s3-')
|
||||
|| line.startsWith('s3.')
|
||||
)
|
||||
&& (
|
||||
line.endsWith('.amazonaws.com')
|
||||
|| line.endsWith('.scw.cloud')
|
||||
)
|
||||
&& !line.includes('cn-')
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
const filePath = path.resolve(__dirname, '../List/non_ip/cdn.conf');
|
||||
const content = (await fs.promises.readFile(filePath, 'utf-8'))
|
||||
.replace(
|
||||
'# --- [AWS S3 Replace Me] ---',
|
||||
S3OSSDomains.map(domain => `DOMAIN-SUFFIX,${domain}`).join('\n')
|
||||
);
|
||||
|
||||
await fs.promises.writeFile(filePath, content, 'utf-8');
|
||||
|
||||
console.timeEnd('Total Time - build-cdn-conf');
|
||||
})();
|
||||
@@ -1,32 +0,0 @@
|
||||
const { fetchWithRetry } = require('./lib/fetch-retry');
|
||||
const { promises: fsPromises } = require('fs');
|
||||
const { resolve: pathResolve } = require('path');
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-chnroutes-cidr');
|
||||
|
||||
const cidr = (await (await fetchWithRetry('https://raw.githubusercontent.com/misakaio/chnroutes2/master/chnroutes.txt')).text()).split('\n');
|
||||
|
||||
const filteredCidr = cidr.filter(line => {
|
||||
if (line) {
|
||||
return !line.startsWith('#')
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
await fsPromises.writeFile(pathResolve(__dirname, '../List/ip/china_ip.conf'), makeCidrList(filteredCidr), { encoding: 'utf-8' });
|
||||
|
||||
console.timeEnd('Total Time - build-chnroutes-cidr');
|
||||
})();
|
||||
|
||||
function makeCidrList(cidr) {
|
||||
const date = new Date();
|
||||
|
||||
return `############################
|
||||
# Mainland China IPv4 CIDR
|
||||
# Data from misaka.io (misakaio @ GitHub)
|
||||
# Last Updated: ${date.toISOString()}
|
||||
# Routes: ${cidr.length}
|
||||
############################\n` + cidr.map(i => `IP-CIDR,${i}`).join('\n') + '\n########### END ############\n';
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
const listDir = require('@sukka/listdir');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const rootPath = path.resolve(__dirname, '../');
|
||||
|
||||
(async () => {
|
||||
const list = await listDir(rootPath, {
|
||||
ignoreHidden: true,
|
||||
ignorePattern: /node_modules|Build|.DS_Store|\.(json|html|md|js)|LICENSE/
|
||||
});
|
||||
|
||||
const html = template(list);
|
||||
|
||||
await fs.promises.writeFile(path.join(rootPath, 'index.html'), html, 'utf-8');
|
||||
})();
|
||||
|
||||
/**
|
||||
* @param {string[]} urlList
|
||||
* @returns {string}
|
||||
*/
|
||||
function template(urlList) {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Surge Ruleset Server | Sukka (@SukkaW)</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
||||
<link href="https://cdn.skk.moe/favicon.ico" rel="icon" type="image/ico">
|
||||
<link href="https://cdn.skk.moe/favicon/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
|
||||
<link href="https://cdn.skk.moe/favicon/android-chrome-192x192.png" rel="icon" type="image/png" sizes="192x192">
|
||||
<link href="https://cdn.skk.moe/favicon/favicon-32x32.png" rel="icon" type="image/png" sizes="32x32">
|
||||
<link href="https://cdn.skk.moe/favicon/favicon-16x16.png" rel="icon" type="image/png" sizes="16x16">
|
||||
<meta name="description" content="Sukka 自用的 Surge 规则组">
|
||||
<meta property="og:title" content="Surge Ruleset | Sukka (@SukkaW)">
|
||||
<meta property="og:type" content="Website">
|
||||
<meta property="og:url" content="https://ruleset.skk.moe/">
|
||||
<meta property="og:image" content="https://cdn.skk.moe/favicon/android-chrome-192x192.png">
|
||||
<meta property="og:description" content="Sukka 自用的 Surge 规则组">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<link rel="canonical" href="https://ruleset.skk.moe/">
|
||||
<link rel="stylesheet" href="https://cdn.staticfile.org/picocss/1.5.0/pico.slim.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<h1>Sukka Surge Ruleset Server</h1>
|
||||
<p>Made by <a href="https://skk.moe">Sukka</a> | <a href="https://github.com/SukkaW/Surge/">Source @ GitHub</a> | Licensed under <a href="https://github.com/SukkaW/Surge/blob/master/LICENSE" target="_blank">AGPL-3.0</a></p>
|
||||
<p>Last Updated: ${new Date().toISOString()}</p>
|
||||
<hr>
|
||||
<br>
|
||||
<ul>
|
||||
${urlList.sort().map(url => `<li><a href="${url}" target="_blank">${url}</a></li>`).join('')}
|
||||
</ul>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
const fsPromises = require('fs').promises;
|
||||
const pathFn = require('path');
|
||||
const table = require('table');
|
||||
const listDir = require('@sukka/listdir');
|
||||
const { green, yellow } = require('picocolors');
|
||||
|
||||
const PRESET_MITM_HOSTNAMES = [
|
||||
// '*baidu.com',
|
||||
'*ydstatic.com',
|
||||
// '*snssdk.com',
|
||||
'*musical.com',
|
||||
// '*musical.ly',
|
||||
// '*snssdk.ly',
|
||||
'api.chelaile.net.cn',
|
||||
'atrace.chelaile.net.cn',
|
||||
'*.meituan.net',
|
||||
'ctrl.playcvn.com',
|
||||
'ctrl.playcvn.net',
|
||||
'ctrl.zmzapi.com',
|
||||
'ctrl.zmzapi.net',
|
||||
'api.zhuishushenqi.com',
|
||||
'b.zhuishushenqi.com',
|
||||
'*.music.126.net',
|
||||
'*.prod.hosts.ooklaserver.net'
|
||||
];
|
||||
|
||||
(async () => {
|
||||
const folderListPath = pathFn.resolve(__dirname, '../List/');
|
||||
const rulesets = await listDir(folderListPath);
|
||||
let urlRegexPaths = [];
|
||||
|
||||
urlRegexPaths.push(
|
||||
...(await fsPromises.readFile(pathFn.join(__dirname, '../Modules/sukka_url_rewrite.sgmodule'), { encoding: 'utf-8' }))
|
||||
.split('\n')
|
||||
.filter(
|
||||
i => !i.startsWith('#')
|
||||
&& !i.startsWith('[')
|
||||
)
|
||||
.map(i => i.split(' ')[0])
|
||||
.map(i => ({
|
||||
origin: i,
|
||||
processed: i
|
||||
.replaceAll('(www.)?', '{www or not}')
|
||||
.replaceAll('^https?://', '')
|
||||
.replaceAll('^https://', '')
|
||||
.replaceAll('^http://', '')
|
||||
.split('/')[0]
|
||||
.replaceAll('\\.', '.')
|
||||
.replaceAll('.+', '*')
|
||||
.replaceAll('(.*)', '*')
|
||||
}))
|
||||
);
|
||||
|
||||
const bothWwwApexDomains = [];
|
||||
urlRegexPaths = urlRegexPaths.map(i => {
|
||||
if (!i.processed.includes('{www or not}')) return i;
|
||||
|
||||
const d = i.processed.replace('{www or not}', '');
|
||||
bothWwwApexDomains.push({
|
||||
origin: i.origin,
|
||||
processed: `www.${d}`
|
||||
});
|
||||
|
||||
return {
|
||||
origin: i.origin,
|
||||
processed: d
|
||||
};
|
||||
});
|
||||
|
||||
urlRegexPaths.push(...bothWwwApexDomains);
|
||||
|
||||
await Promise.all(rulesets.map(async file => {
|
||||
const content = (await fsPromises.readFile(pathFn.join(folderListPath, file), { encoding: 'utf-8' })).split('\n');
|
||||
urlRegexPaths.push(
|
||||
...content
|
||||
.filter(i => i.startsWith('URL-REGEX'))
|
||||
.map(i => i.split(',')[1])
|
||||
.map(i => ({
|
||||
origin: i,
|
||||
processed: i
|
||||
.replaceAll('^https?://', '')
|
||||
.replaceAll('^https://', '')
|
||||
.replaceAll('^http://', '')
|
||||
.replaceAll('\\.', '.')
|
||||
.replaceAll('.+', '*')
|
||||
.replaceAll('\\d', '*')
|
||||
.replaceAll('([a-z])', '*')
|
||||
.replaceAll('[a-z]', '*')
|
||||
.replaceAll('([0-9])', '*')
|
||||
.replaceAll('[0-9]', '*')
|
||||
.replaceAll(/{.+?}/g, '')
|
||||
.replaceAll(/\*+/g, '*')
|
||||
}))
|
||||
);
|
||||
}));
|
||||
|
||||
let mitmDomains = new Set(PRESET_MITM_HOSTNAMES); // Special case for parsed failed
|
||||
const parsedFailures = new Set();
|
||||
|
||||
const dedupedUrlRegexPaths = [...new Set(urlRegexPaths)];
|
||||
|
||||
dedupedUrlRegexPaths.forEach(i => {
|
||||
const result = parseDomain(i.processed);
|
||||
|
||||
if (result.success) {
|
||||
mitmDomains.add(result.hostname.trim());
|
||||
} else {
|
||||
parsedFailures.add(i.origin);
|
||||
}
|
||||
});
|
||||
|
||||
mitmDomains = [...mitmDomains].filter(i => {
|
||||
return i.length > 3
|
||||
&& !i.includes('.mp4') // Special Case
|
||||
&& i !== '(www.)' // Special Case
|
||||
&& !(i !== '*.meituan.net' && i.endsWith('.meituan.net'))
|
||||
&& !i.startsWith('.')
|
||||
&& !i.endsWith('.')
|
||||
&& !i.endsWith('*')
|
||||
});
|
||||
|
||||
const mitmDomainsRegExpArray = mitmDomains.map(i => {
|
||||
return new RegExp(
|
||||
escapeRegExp(i)
|
||||
.replaceAll('{www or not}', '(www.)?')
|
||||
.replaceAll('\\*', '(.*)')
|
||||
)
|
||||
});
|
||||
|
||||
const parsedDomainsData = [];
|
||||
dedupedUrlRegexPaths.forEach(i => {
|
||||
const result = parseDomain(i.processed);
|
||||
|
||||
if (result.success) {
|
||||
if (matchWithRegExpArray(result.hostname.trim(), mitmDomainsRegExpArray)) {
|
||||
parsedDomainsData.push([green(result.hostname), i.origin]);
|
||||
} else {
|
||||
parsedDomainsData.push([yellow(result.hostname), i.origin]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Mitm Hostnames:');
|
||||
console.log('hostname = %APPEND% ' + mitmDomains.join(', '));
|
||||
console.log('--------------------');
|
||||
console.log('Parsed Sucessed:');
|
||||
console.log(table.table(parsedDomainsData, {
|
||||
border: table.getBorderCharacters('void'),
|
||||
columnDefault: {
|
||||
paddingLeft: 0,
|
||||
paddingRight: 3
|
||||
},
|
||||
drawHorizontalLine: () => false
|
||||
}));
|
||||
console.log('--------------------');
|
||||
console.log('Parsed Failed');
|
||||
console.log([...parsedFailures].join('\n'));
|
||||
})();
|
||||
|
||||
/** Util function */
|
||||
function parseDomain(input) {
|
||||
try {
|
||||
const url = new URL(`https://${input}`);
|
||||
return {
|
||||
success: true,
|
||||
hostname: url.hostname
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
success: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function matchWithRegExpArray(input, regexps = []) {
|
||||
for (const r of regexps) {
|
||||
if (r.test(input)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function escapeRegExp(string = '') {
|
||||
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
||||
const reHasRegExpChar = RegExp(reRegExpChar.source);
|
||||
|
||||
return string && reHasRegExpChar.test(string)
|
||||
? string.replace(reRegExpChar, '\\$&')
|
||||
: string;
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
const psl = require('psl');
|
||||
const { processFilterRules } = require('./lib/parse-filter.js');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const WHITELIST_DOMAIN = new Set([]);
|
||||
const BLACK_TLD = [
|
||||
'.xyz',
|
||||
'.top',
|
||||
'.win',
|
||||
'.vip',
|
||||
'.site',
|
||||
'.space',
|
||||
'.online',
|
||||
'.icu',
|
||||
'.fun',
|
||||
'.shop',
|
||||
'.cool',
|
||||
'.cyou',
|
||||
'.id',
|
||||
'.pro'
|
||||
];
|
||||
|
||||
(async () => {
|
||||
const domainSet = Array.from(
|
||||
(
|
||||
await processFilterRules('https://curbengh.github.io/phishing-filter/phishing-filter-agh.txt')
|
||||
).black
|
||||
);
|
||||
const domainCountMap = {};
|
||||
|
||||
for (let i = 0, len = domainSet.length; i < len; i++) {
|
||||
const line = domainSet[i];
|
||||
// starts with #
|
||||
if (line.charCodeAt(0) === 35) {
|
||||
continue;
|
||||
}
|
||||
if (line.trim().length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const domain = line.charCodeAt(0) === 46 ? line.slice(1) : line;
|
||||
|
||||
if (line.length > 25) {
|
||||
const parsed = psl.parse(domain);
|
||||
|
||||
if (parsed.input === parsed.tld) {
|
||||
continue;
|
||||
}
|
||||
const apexDomain = parsed.domain
|
||||
|
||||
if (WHITELIST_DOMAIN.has(apexDomain)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
domainCountMap[apexDomain] ||= 0;
|
||||
domainCountMap[apexDomain] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const results = [];
|
||||
Object.entries(domainCountMap).forEach(([domain, count]) => {
|
||||
if (
|
||||
count >= 8
|
||||
&& BLACK_TLD.some(tld => domain.endsWith(tld))
|
||||
) {
|
||||
results.push('.' + domain);
|
||||
}
|
||||
});
|
||||
|
||||
const filePath = path.resolve(__dirname, '../List/domainset/reject_phishing.conf');
|
||||
await fs.promises.writeFile(filePath, results.join('\n'), 'utf-8');
|
||||
})();
|
||||
@@ -1,330 +0,0 @@
|
||||
const { promises: fsPromises } = require('fs');
|
||||
const { resolve: pathResolve } = require('path');
|
||||
const Piscina = require('piscina');
|
||||
const { processHosts, processFilterRules, preprocessFullDomainSetBeforeUsedAsWorkerData } = require('./lib/parse-filter');
|
||||
const cpuCount = require('os').cpus().length;
|
||||
const { isCI } = require('ci-info');
|
||||
const threads = isCI ? cpuCount : cpuCount / 2;
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-reject-domain-set');
|
||||
|
||||
/** @type Set<string> */
|
||||
const domainSets = new Set();
|
||||
|
||||
console.log('Downloading hosts file...');
|
||||
console.time('* Download and process Hosts');
|
||||
|
||||
// Parse from remote hosts & domain lists
|
||||
(await Promise.all([
|
||||
processHosts('https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext', true),
|
||||
processHosts('https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/hosts.txt'),
|
||||
processHosts('https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt')
|
||||
])).forEach(hosts => {
|
||||
hosts.forEach(host => {
|
||||
if (host) {
|
||||
domainSets.add(host);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
console.timeEnd('* Download and process Hosts');
|
||||
|
||||
let previousSize = domainSets.size;
|
||||
console.log(`Import ${previousSize} rules from hosts files!`);
|
||||
|
||||
await fsPromises.readFile(pathResolve(__dirname, '../List/domainset/reject_sukka.conf'), { encoding: 'utf-8' }).then(data => {
|
||||
data.split('\n').forEach(line => {
|
||||
const trimmed = line.trim();
|
||||
if (
|
||||
line.startsWith('#')
|
||||
|| line.startsWith(' ')
|
||||
|| line.startsWith('\r')
|
||||
|| line.startsWith('\n')
|
||||
|| trimmed === ''
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if (domainSets.has(line) || domainSets.has(`.${line}`)) {
|
||||
console.warn(`|${line}| is already in the list!`);
|
||||
} */
|
||||
domainSets.add(trimmed);
|
||||
});
|
||||
});
|
||||
|
||||
previousSize = domainSets.size - previousSize;
|
||||
console.log(`Import ${previousSize} rules from reject_sukka.conf!`);
|
||||
|
||||
// Parse from AdGuard Filters
|
||||
/** @type Set<string> */
|
||||
const filterRuleWhitelistDomainSets = new Set([
|
||||
'localhost',
|
||||
'broadcasthost',
|
||||
'ip6-loopback',
|
||||
'ip6-localnet',
|
||||
'ip6-mcastprefix',
|
||||
'ip6-allnodes',
|
||||
'ip6-allrouters',
|
||||
'ip6-allhosts',
|
||||
'mcastprefix',
|
||||
'skk.moe',
|
||||
'analytics.google.com',
|
||||
'msa.cdn.mediaset.net', // Added manually using DOMAIN-KEYWORDS
|
||||
'cloud.answerhub.com',
|
||||
'ae01.alicdn.com',
|
||||
'whoami.akamai.net',
|
||||
'whoami.ds.akahelp.net',
|
||||
'pxlk9.net.', // This one is malformed from EasyList, which I will manually add instead
|
||||
'instant.page', // No, it doesn't violate anyone's privacy. I will whitelist it
|
||||
'piwik.pro',
|
||||
'mixpanel.com',
|
||||
'cdn.mxpnl.com',
|
||||
'heapanalytics.com',
|
||||
'segment.com',
|
||||
'segmentify.com',
|
||||
't.co', // pgl yoyo add t.co to the blacklist
|
||||
'survicate.com', // AdGuardDNSFilter
|
||||
'perfops.io', // AdGuardDNSFilter
|
||||
'd2axgrpnciinw7.cloudfront.net', // ADGuardDNSFilter
|
||||
'tb-lb.sb-cd.com', // AdGuard
|
||||
'storage.yandexcloud.net', // phishing list
|
||||
'login.microsoftonline.com' // phishing list
|
||||
]);
|
||||
|
||||
console.time('* Download and process AdBlock Filter Rules');
|
||||
(await Promise.all([
|
||||
// Easy List
|
||||
[
|
||||
'https://easylist.to/easylist/easylist.txt',
|
||||
[
|
||||
'https://easylist-downloads.adblockplus.org/easylist.txt',
|
||||
'https://raw.githubusercontent.com/easylist/easylist/gh-pages/easylist.txt',
|
||||
'https://secure.fanboy.co.nz/easylist.txt'
|
||||
]
|
||||
],
|
||||
// AdGuard DNS Filter
|
||||
'https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt',
|
||||
// uBlock Origin Filter List
|
||||
'https://ublockorigin.github.io/uAssetsCDN/filters/filters.txt',
|
||||
'https://ublockorigin.github.io/uAssetsCDN/filters/filters-2020.txt',
|
||||
'https://ublockorigin.github.io/uAssetsCDN/filters/filters-2021.txt',
|
||||
'https://ublockorigin.github.io/uAssetsCDN/filters/filters-2022.txt',
|
||||
// uBlock Origin Badware Risk List
|
||||
'https://ublockorigin.github.io/uAssets/filters/badware.txt',
|
||||
// uBlock Origin Privacy List
|
||||
'https://ublockorigin.github.io/uAssets/filters/privacy.txt',
|
||||
// uBlock Origin Resource Abuse
|
||||
'https://ublockorigin.github.io/uAssets/filters/resource-abuse.txt',
|
||||
// uBlock Origin Unbreak
|
||||
'https://ublockorigin.github.io/uAssets/filters/unbreak.txt',
|
||||
// AdGuard Base Filter
|
||||
'https://filters.adtidy.org/extension/ublock/filters/2_without_easylist.txt',
|
||||
// AdGuard Mobile AD
|
||||
'https://filters.adtidy.org/extension/ublock/filters/11.txt',
|
||||
// AdGuard Tracking Protection
|
||||
'https://filters.adtidy.org/extension/ublock/filters/3.txt',
|
||||
// AdGuard Japanese filter
|
||||
'https://filters.adtidy.org/extension/ublock/filters/7.txt',
|
||||
// AdGuard Chinese filter (EasyList China + AdGuard Chinese filter)
|
||||
'https://filters.adtidy.org/extension/ublock/filters/224.txt',
|
||||
// Easy Privacy
|
||||
[
|
||||
'https://easylist.to/easylist/easyprivacy.txt',
|
||||
[
|
||||
'https://secure.fanboy.co.nz/easyprivacy.txt',
|
||||
'https://raw.githubusercontent.com/easylist/easylist/gh-pages/easyprivacy.txt',
|
||||
'https://easylist-downloads.adblockplus.org/easyprivacy.txt'
|
||||
]
|
||||
],
|
||||
// Curben's UrlHaus Malicious URL Blocklist
|
||||
// Prefer mirror, since malware-filter.gitlab.io has not been updated for a while
|
||||
'https://curbengh.github.io/urlhaus-filter/urlhaus-filter-agh-online.txt',
|
||||
// [
|
||||
// 'https://malware-filter.pages.dev/urlhaus-filter-agh-online.txt',
|
||||
// [
|
||||
// 'https://malware-filter.gitlab.io/urlhaus-filter/urlhaus-filter-agh-online.txt'
|
||||
// ]
|
||||
// ],
|
||||
// Curben's Phishing URL Blocklist
|
||||
// Prefer mirror, since malware-filter.gitlab.io has not been updated for a while
|
||||
'https://curbengh.github.io/phishing-filter/phishing-filter-agh.txt',
|
||||
// [
|
||||
// 'https://phishing-filter.pages.dev/phishing-filter-agh.txt',
|
||||
// [
|
||||
// 'https://malware-filter.gitlab.io/malware-filter/phishing-filter-agh.txt'
|
||||
// ]
|
||||
// ],
|
||||
// Curben's PUP Domains Blocklist
|
||||
'https://curbengh.github.io/pup-filter/pup-filter-agh.txt',
|
||||
// Prefer mirror, since malware-filter.gitlab.io has not been updated for a while
|
||||
// [
|
||||
// 'https://pup-filter.pages.dev/pup-filter-agh.txt',
|
||||
// [
|
||||
// 'https://malware-filter.gitlab.io/malware-filter/pup-filter-agh.txt'
|
||||
// ]
|
||||
// ],
|
||||
// GameConsoleAdblockList
|
||||
'https://raw.githubusercontent.com/DandelionSprout/adfilt/master/GameConsoleAdblockList.txt',
|
||||
// PiHoleBlocklist
|
||||
'https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV-AGH.txt',
|
||||
// Spam404
|
||||
'https://raw.githubusercontent.com/Spam404/lists/master/adblock-list.txt'
|
||||
].map(input => {
|
||||
if (typeof input === 'string') {
|
||||
return processFilterRules(input);
|
||||
}
|
||||
if (Array.isArray(input) && input.length === 2) {
|
||||
return processFilterRules(input[0], input[1]);
|
||||
}
|
||||
}))).forEach(({ white, black }) => {
|
||||
white.forEach(i => filterRuleWhitelistDomainSets.add(i));
|
||||
black.forEach(i => domainSets.add(i));
|
||||
});
|
||||
|
||||
console.timeEnd('* Download and process AdBlock Filter Rules');
|
||||
|
||||
previousSize = domainSets.size - previousSize;
|
||||
console.log(`Import ${previousSize} rules from adguard filters!`);
|
||||
|
||||
// Read DOMAIN Keyword
|
||||
const domainKeywordsSet = new Set();
|
||||
const domainSuffixSet = new Set();
|
||||
await fsPromises.readFile(pathResolve(__dirname, '../List/non_ip/reject.conf'), { encoding: 'utf-8' }).then(data => {
|
||||
data.split('\n').forEach(line => {
|
||||
if (line.startsWith('DOMAIN-KEYWORD')) {
|
||||
const [, ...keywords] = line.split(',');
|
||||
domainKeywordsSet.add(keywords.join(',').trim());
|
||||
} else if (line.startsWith('DOMAIN-SUFFIX')) {
|
||||
const [, ...keywords] = line.split(',');
|
||||
domainSuffixSet.add(keywords.join(',').trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Read Special Phishing Suffix list
|
||||
await fsPromises.readFile(pathResolve(__dirname, '../List/domainset/reject_phishing.conf'), { encoding: 'utf-8' }).then(data => {
|
||||
data.split('\n').forEach(line => {
|
||||
const trimmed = line.trim();
|
||||
if (
|
||||
line.startsWith('#')
|
||||
|| line.startsWith(' ')
|
||||
|| line.startsWith('\r')
|
||||
|| line.startsWith('\n')
|
||||
|| trimmed === ''
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if (domainSets.has(line) || domainSets.has(`.${line}`)) {
|
||||
console.warn(`|${line}| is already in the list!`);
|
||||
} */
|
||||
domainSuffixSet.add(trimmed);
|
||||
});
|
||||
});
|
||||
|
||||
console.log(`Import ${domainKeywordsSet.size} black keywords and ${domainSuffixSet.size} black suffixes!`);
|
||||
|
||||
previousSize = domainSets.size;
|
||||
// Dedupe domainSets
|
||||
console.log(`Start deduping from black keywords/suffixes! (${previousSize})`);
|
||||
console.time(`* Dedupe from black keywords/suffixes`);
|
||||
|
||||
for (const domain of domainSets) {
|
||||
let isTobeRemoved = false;
|
||||
|
||||
for (const keyword of domainKeywordsSet) {
|
||||
if (domain.includes(keyword)) {
|
||||
isTobeRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isTobeRemoved) {
|
||||
for (const suffix of domainSuffixSet) {
|
||||
if (domain.endsWith(suffix)) {
|
||||
isTobeRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isTobeRemoved) {
|
||||
for (const white of filterRuleWhitelistDomainSets) {
|
||||
if (domain.includes(white) || white.includes(domain)) {
|
||||
isTobeRemoved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isTobeRemoved) {
|
||||
domainSets.delete(domain);
|
||||
}
|
||||
}
|
||||
|
||||
console.timeEnd(`* Dedupe from black keywords/suffixes`);
|
||||
console.log(`Deduped ${previousSize} - ${domainSets.size} = ${previousSize - domainSets.size} from black keywords and suffixes!`);
|
||||
|
||||
previousSize = domainSets.size;
|
||||
// Dedupe domainSets
|
||||
console.log(`Start deduping! (${previousSize})`);
|
||||
|
||||
const START_TIME = Date.now();
|
||||
|
||||
const piscina = new Piscina({
|
||||
filename: pathResolve(__dirname, 'worker/build-reject-domainset-worker.js'),
|
||||
workerData: preprocessFullDomainSetBeforeUsedAsWorkerData([...domainSets]),
|
||||
idleTimeout: 50,
|
||||
minThreads: threads,
|
||||
maxThreads: threads
|
||||
});
|
||||
|
||||
console.log(`Launching ${threads} threads...`)
|
||||
|
||||
const tasksArray = Array.from(domainSets)
|
||||
.reduce((result, element, index) => {
|
||||
const chunk = index % threads;
|
||||
result[chunk] ??= [];
|
||||
|
||||
result[chunk].push(element);
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
(
|
||||
await Promise.all(
|
||||
Array.from(domainSets)
|
||||
.reduce((result, element, index) => {
|
||||
const chunk = index % threads;
|
||||
result[chunk] ??= [];
|
||||
result[chunk].push(element);
|
||||
return result;
|
||||
}, [])
|
||||
.map(chunk => piscina.run({ chunk }, { name: 'dedupe' }))
|
||||
)
|
||||
).forEach((result, taskIndex) => {
|
||||
const chunk = tasksArray[taskIndex];
|
||||
result.forEach((value, index) => {
|
||||
if (value === 1) {
|
||||
domainSets.delete(chunk[index])
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
console.log(`* Dedupe from covered subdomain - ${(Date.now() - START_TIME) / 1000}s`);
|
||||
console.log(`Deduped ${previousSize - domainSets.size} rules!`);
|
||||
|
||||
await Promise.all([
|
||||
fsPromises.writeFile(
|
||||
pathResolve(__dirname, '../List/domainset/reject.conf'),
|
||||
`${[...domainSets].join('\n')}\n`,
|
||||
{ encoding: 'utf-8' }
|
||||
),
|
||||
piscina.destroy()
|
||||
]);
|
||||
|
||||
console.timeEnd('Total Time - build-reject-domain-set');
|
||||
if (piscina.queueSize === 0) {
|
||||
process.exit(0);
|
||||
}
|
||||
})();
|
||||
@@ -1,34 +0,0 @@
|
||||
const { fetchWithRetry } = require('./lib/fetch-retry');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { isIPv4, isIPv6 } = require('net');
|
||||
|
||||
(async () => {
|
||||
console.time('Total Time - build-telegram-cidr');
|
||||
|
||||
const resp = await fetchWithRetry('https://core.telegram.org/resources/cidr.txt');
|
||||
const lastModified = new Date(resp.headers.get('last-modified'));
|
||||
|
||||
const res = (await resp.text())
|
||||
.split('\n')
|
||||
.filter(line => line.trim() !== '');
|
||||
|
||||
await fs.promises.writeFile(
|
||||
path.resolve(__dirname, '../List/ip/telegram.conf'),
|
||||
'# Telegram CIDR (https://core.telegram.org/resources/cidr.txt)' + '\n' +
|
||||
'# Last Updated: ' + lastModified.toISOString() + '\n' +
|
||||
res.map(ip => {
|
||||
const [subnet] = ip.split('/');
|
||||
if (isIPv4(subnet)) {
|
||||
return `IP-CIDR,${ip},no-resolve`;
|
||||
}
|
||||
if (isIPv6(subnet)) {
|
||||
return `IP-CIDR6,${ip},no-resolve`;
|
||||
}
|
||||
return '';
|
||||
}).join('\n') + '\n',
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
console.timeEnd('Total Time - build-telegram-cidr');
|
||||
})();
|
||||
@@ -1,3 +0,0 @@
|
||||
const { fetch } = require('undici');
|
||||
const fetchWithRetry = require('@vercel/fetch-retry')(fetch);
|
||||
module.exports.fetchWithRetry = fetchWithRetry;
|
||||
@@ -1,248 +0,0 @@
|
||||
const { isIP } = require('net');
|
||||
const { fetchWithRetry } = require('./fetch-retry');
|
||||
|
||||
const rDomain = /^(((?!\-))(xn\-\-)?[a-z0-9\-_]{0,61}[a-z0-9]{1,1}\.)*(xn\-\-)?([a-z0-9\-]{1,61}|[a-z0-9\-]{1,30})\.[a-z]{2,}$/m
|
||||
|
||||
const DEBUG_DOMAIN_TO_FIND = null; // example.com | null
|
||||
|
||||
const warnOnceUrl = new Set();
|
||||
const warnOnce = (url, isWhite, ...message) => {
|
||||
const key = `${url}${isWhite ? 'white' : 'black'}`;
|
||||
if (warnOnceUrl.has(key)) {
|
||||
return;
|
||||
}
|
||||
warnOnceUrl.add(key);
|
||||
console.warn(url, isWhite ? '(white)' : '(black)', ...message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | URL} domainListsUrl
|
||||
*/
|
||||
async function processDomainLists (domainListsUrl) {
|
||||
if (typeof domainListsUrl === 'string') {
|
||||
domainListsUrl = new URL(domainListsUrl);
|
||||
}
|
||||
|
||||
/** @type Set<string> */
|
||||
const domainSets = new Set();
|
||||
/** @type string[] */
|
||||
const domains = (await (await fetchWithRetry(domainListsUrl)).text()).split('\n');
|
||||
domains.forEach(line => {
|
||||
if (
|
||||
line.startsWith('#')
|
||||
|| line.startsWith('!')
|
||||
|| line.startsWith(' ')
|
||||
|| line === ''
|
||||
|| line.startsWith('\r')
|
||||
|| line.startsWith('\n')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const domainToAdd = line.trim();
|
||||
|
||||
if (DEBUG_DOMAIN_TO_FIND && domainToAdd.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(domainListsUrl.toString(), false, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
domainSets.add(domainToAdd);
|
||||
});
|
||||
|
||||
return [...domainSets];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | URL} hostsUrl
|
||||
*/
|
||||
async function processHosts (hostsUrl, includeAllSubDomain = false) {
|
||||
console.time(` - processHosts: ${hostsUrl}`);
|
||||
|
||||
if (typeof hostsUrl === 'string') {
|
||||
hostsUrl = new URL(hostsUrl);
|
||||
}
|
||||
|
||||
/** @type Set<string> */
|
||||
const domainSets = new Set();
|
||||
|
||||
/** @type string[] */
|
||||
const hosts = (await (await fetchWithRetry(hostsUrl)).text()).split('\n');
|
||||
hosts.forEach(line => {
|
||||
if (line.includes('#')) {
|
||||
return;
|
||||
}
|
||||
if (line.startsWith(' ') || line.startsWith('\r') || line.startsWith('\n') || line.trim() === '') {
|
||||
return;
|
||||
}
|
||||
const [, ...domains] = line.split(' ');
|
||||
const domain = domains.join(' ').trim();
|
||||
|
||||
if (DEBUG_DOMAIN_TO_FIND && domain.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(hostsUrl.toString(), false, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
if (rDomain.test(domain)) {
|
||||
if (includeAllSubDomain) {
|
||||
domainSets.add(`.${domain}`);
|
||||
} else {
|
||||
domainSets.add(domain);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.timeEnd(` - processHosts: ${hostsUrl}`);
|
||||
|
||||
return [...domainSets];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | URL} filterRulesUrl
|
||||
* @param {(string | URL)[] | undefined} fallbackUrls
|
||||
* @returns {Promise<{ white: Set<string>, black: Set<string> }>}
|
||||
*/
|
||||
async function processFilterRules (filterRulesUrl, fallbackUrls) {
|
||||
console.time(` - processFilterRules: ${filterRulesUrl}`);
|
||||
|
||||
/** @type Set<string> */
|
||||
const whitelistDomainSets = new Set();
|
||||
/** @type Set<string> */
|
||||
const blacklistDomainSets = new Set();
|
||||
|
||||
let filterRules;
|
||||
try {
|
||||
/** @type string[] */
|
||||
filterRules = (
|
||||
await Promise.any(
|
||||
[filterRulesUrl, ...(fallbackUrls || [])].map(
|
||||
async url => (await fetchWithRetry(url)).text()
|
||||
)
|
||||
)
|
||||
).split('\n').map(line => line.trim());
|
||||
} catch (e) {
|
||||
console.log('Download Rule for [' + filterRulesUrl + '] failed');
|
||||
throw e;
|
||||
}
|
||||
|
||||
filterRules.forEach(line => {
|
||||
const lineStartsWithDoubleVerticalBar = line.startsWith('||');
|
||||
|
||||
if (
|
||||
line === ''
|
||||
|| line.includes('#')
|
||||
|| line.includes('!')
|
||||
|| line.includes('*')
|
||||
|| line.includes('/')
|
||||
|| line.includes('[')
|
||||
|| line.includes('$') && !lineStartsWithDoubleVerticalBar
|
||||
|| line === ''
|
||||
|| isIP(line) !== 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lineEndsWithCaret = line.endsWith('^');
|
||||
const lineEndsWithCaretVerticalBar = line.endsWith('^|');
|
||||
|
||||
if (lineStartsWithDoubleVerticalBar && line.endsWith('^$badfilter')) {
|
||||
const domain = line.replace('||', '').replace('^$badfilter', '').trim();
|
||||
if (rDomain.test(domain)) {
|
||||
if (DEBUG_DOMAIN_TO_FIND && domain.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(filterRulesUrl.toString(), true, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
whitelistDomainSets.add(domain);
|
||||
}
|
||||
} else if (line.startsWith('@@||')
|
||||
&& (
|
||||
lineEndsWithCaret
|
||||
|| lineEndsWithCaretVerticalBar
|
||||
|| line.endsWith('^$badfilter')
|
||||
|| line.endsWith('^$1p')
|
||||
)
|
||||
) {
|
||||
const domain = line
|
||||
.replaceAll('@@||', '')
|
||||
.replaceAll('^$badfilter', '')
|
||||
.replaceAll('^$1p', '')
|
||||
.replaceAll('^|', '')
|
||||
.replaceAll('^', '')
|
||||
.trim();
|
||||
if (rDomain.test(domain)) {
|
||||
if (DEBUG_DOMAIN_TO_FIND && domain.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(filterRulesUrl.toString(), true, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
whitelistDomainSets.add(domain);
|
||||
}
|
||||
} else if (
|
||||
lineStartsWithDoubleVerticalBar
|
||||
&& (
|
||||
lineEndsWithCaret
|
||||
|| lineEndsWithCaretVerticalBar
|
||||
|| line.endsWith('^$all')
|
||||
)
|
||||
) {
|
||||
const domain = line
|
||||
.replaceAll('||', '')
|
||||
.replaceAll('^|', '')
|
||||
.replaceAll('^$all', '')
|
||||
.replaceAll('^', '')
|
||||
.trim();
|
||||
if (rDomain.test(domain)) {
|
||||
|
||||
if (DEBUG_DOMAIN_TO_FIND && domain.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(filterRulesUrl.toString(), false, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
blacklistDomainSets.add(`.${domain}`);
|
||||
}
|
||||
} else if (line.startsWith('://')
|
||||
&& (
|
||||
lineEndsWithCaret
|
||||
|| lineEndsWithCaretVerticalBar
|
||||
)
|
||||
) {
|
||||
const domain = `${line.replaceAll('://', '').replaceAll('^|', '').replaceAll('^', '')}`.trim();
|
||||
if (rDomain.test(domain)) {
|
||||
|
||||
if (DEBUG_DOMAIN_TO_FIND && domain.includes(DEBUG_DOMAIN_TO_FIND)) {
|
||||
warnOnce(filterRulesUrl.toString(), false, DEBUG_DOMAIN_TO_FIND);
|
||||
}
|
||||
|
||||
blacklistDomainSets.add(domain);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.timeEnd(` - processFilterRules: ${filterRulesUrl}`);
|
||||
|
||||
return {
|
||||
white: whitelistDomainSets,
|
||||
black: blacklistDomainSets
|
||||
};
|
||||
}
|
||||
|
||||
function preprocessFullDomainSetBeforeUsedAsWorkerData (data) {
|
||||
return data.filter(domain => (
|
||||
domain.charCodeAt(0) === 46
|
||||
&& !canExcludeFromDedupe(domain)
|
||||
));
|
||||
}
|
||||
|
||||
// duckdns.org domain will not overlap and doesn't need dedupe
|
||||
function canExcludeFromDedupe (domain) {
|
||||
if (
|
||||
// starts with a dot
|
||||
domain.charCodeAt(0) === 46
|
||||
&& domain.length === 23
|
||||
&& domain.endsWith('.duckdns.org')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports.processDomainLists = processDomainLists;
|
||||
module.exports.processHosts = processHosts;
|
||||
module.exports.processFilterRules = processFilterRules;
|
||||
module.exports.preprocessFullDomainSetBeforeUsedAsWorkerData = preprocessFullDomainSetBeforeUsedAsWorkerData;
|
||||
module.exports.canExcludeFromDedupe = canExcludeFromDedupe;
|
||||
@@ -1,57 +0,0 @@
|
||||
const psl = require('psl');
|
||||
const picocolors = require('picocolors');
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
(async () => {
|
||||
const domainSetContent = await fs.promises.readFile(
|
||||
path.resolve(__dirname, '../List/domainset/cdn.conf'),
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
|
||||
const domainSetLines = domainSetContent.split('\n');
|
||||
for (let i = 0, len = domainSetLines.length; i < len; i++) {
|
||||
const line = domainSetLines[i];
|
||||
// starts with #
|
||||
if (line.charCodeAt(0) === 35) {
|
||||
continue;
|
||||
}
|
||||
if (line.trim().length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const domain = line.charCodeAt(0) === 46 ? line.slice(1) : line;
|
||||
const parsed = psl.parse(domain);
|
||||
|
||||
if (parsed.listed && parsed.input === parsed.tld) {
|
||||
console.error('Domain', picocolors.yellow(domain), picocolors.red('is in public suffix list!'));
|
||||
}
|
||||
}
|
||||
|
||||
const rulesetContent = await fs.promises.readFile(
|
||||
path.resolve(__dirname, '../List/non_ip/cdn.conf'),
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
const rulesetLines = rulesetContent.split('\n');
|
||||
|
||||
for (let i = 0, len = rulesetLines.length; i < len; i++) {
|
||||
const line = rulesetLines[i];
|
||||
// starts with #
|
||||
if (line.charCodeAt(0) === 35) {
|
||||
continue;
|
||||
}
|
||||
if (line.trim().length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.startsWith('DOMAIN-SUFFIX')) {
|
||||
const domain = line.slice(14);
|
||||
const parsed = psl.parse(domain);
|
||||
|
||||
if (parsed.input !== parsed.tld) {
|
||||
console.error('Domain', picocolors.yellow(domain), picocolors.green('is not in public suffix list!'));
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -1,56 +0,0 @@
|
||||
const Piscina = require('piscina');
|
||||
const { canExcludeFromDedupe } = require('../lib/parse-filter')
|
||||
|
||||
const fullsetDomainStartsWithADot = Piscina.workerData
|
||||
const totalLen = fullsetDomainStartsWithADot.length;
|
||||
|
||||
module.exports.dedupe = ({ chunk }) => {
|
||||
const chunkLength = chunk.length;
|
||||
const outputToBeRemoved = new Int8Array(chunkLength);
|
||||
|
||||
for (let i = 0; i < chunkLength; i++) {
|
||||
const domainFromInput = chunk[i];
|
||||
|
||||
if (canExcludeFromDedupe(domainFromInput)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let j = 0; j < totalLen; j++) {
|
||||
const domainFromFullSet = fullsetDomainStartsWithADot[j];
|
||||
// domainFromFullSet is now startsWith a "."
|
||||
|
||||
if (domainFromFullSet === domainFromInput) continue;
|
||||
|
||||
const domainFromInputLen = domainFromInput.length;
|
||||
const domainFromFullSetLen = domainFromFullSet.length;
|
||||
|
||||
// !domainFromInput.starsWith('.') && `.${domainFromInput}` === domainFromFullSet
|
||||
if (domainFromInput.charCodeAt(0) !== 46) {
|
||||
if (domainFromInputLen + 1 === domainFromFullSetLen) {
|
||||
|
||||
let shouldBeRemoved = true;
|
||||
|
||||
for (let k = 0; k < domainFromInputLen; k++) {
|
||||
if (domainFromFullSet.charCodeAt(k + 1) !== domainFromInput.charCodeAt(k)) {
|
||||
shouldBeRemoved = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldBeRemoved) {
|
||||
outputToBeRemoved[i] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (domainFromInputLen > domainFromFullSetLen) {
|
||||
// domainFromInput is now startsWith a "."
|
||||
if (domainFromInput.endsWith(domainFromFullSet)) {
|
||||
outputToBeRemoved[i] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Piscina.move(outputToBeRemoved);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
############################
|
||||
# Mainland China IPv4 CIDR
|
||||
# Data from misaka.io (misakaio @ GitHub)
|
||||
# Last Updated: 2022-11-01T12:14:31.663Z
|
||||
# Last Updated: 2022-11-01T12:19:49.696Z
|
||||
# Routes: 3183
|
||||
############################
|
||||
IP-CIDR,1.2.4.0/24
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<main class="container">
|
||||
<h1>Sukka Surge Ruleset Server</h1>
|
||||
<p>Made by <a href="https://skk.moe">Sukka</a> | <a href="https://github.com/SukkaW/Surge/">Source @ GitHub</a> | Licensed under <a href="https://github.com/SukkaW/Surge/blob/master/LICENSE" target="_blank">AGPL-3.0</a></p>
|
||||
<p>Last Updated: 2022-11-01T12:16:42.581Z</p>
|
||||
<p>Last Updated: 2022-11-01T12:21:57.063Z</p>
|
||||
<hr>
|
||||
<br>
|
||||
<ul>
|
||||
|
||||
88
package.json
88
package.json
@@ -1,88 +0,0 @@
|
||||
{
|
||||
"name": "ruleset.skk.moe",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"build": "wireit",
|
||||
"build:anti-bogus-domain": "wireit",
|
||||
"build:apple-cdn": "wireit",
|
||||
"build:cdn-conf": "wireit",
|
||||
"build:index-html": "wireit",
|
||||
"build:reject-domainset": "wireit",
|
||||
"build:phishing-domainset": "wireit",
|
||||
"build:telegram-cidr": "wireit",
|
||||
"build:chn-cidr": "wireit",
|
||||
"validate:cdn-conf": "wireit"
|
||||
},
|
||||
"wireit": {
|
||||
"build:anti-bogus-domain": {
|
||||
"command": "node ./Build/build-anti-bogus-domain.js"
|
||||
},
|
||||
"build:apple-cdn": {
|
||||
"command": "node ./Build/build-apple-cdn.js"
|
||||
},
|
||||
"build:cdn-conf": {
|
||||
"command": "node ./Build/build-cdn-conf.js"
|
||||
},
|
||||
"build:phishing-domainset": {
|
||||
"command": "node ./Build/build-phishing-domainset.js"
|
||||
},
|
||||
"build:reject-domainset": {
|
||||
"command": "node ./Build/build-reject-domainset.js",
|
||||
"dependencies": [
|
||||
"build:phishing-domainset"
|
||||
]
|
||||
},
|
||||
"build:telegram-cidr": {
|
||||
"command": "node ./Build/build-telegram-cidr.js"
|
||||
},
|
||||
"build:chn-cidr": {
|
||||
"command": "node ./Build/build-chn-cidr.js"
|
||||
},
|
||||
"build:index-html": {
|
||||
"command": "node ./Build/build-index.html.js",
|
||||
"dependencies": [
|
||||
"build:anti-bogus-domain",
|
||||
"build:apple-cdn",
|
||||
"build:cdn-conf",
|
||||
"build:reject-domainset",
|
||||
"build:telegram-cidr"
|
||||
]
|
||||
},
|
||||
"validate:cdn-conf": {
|
||||
"command": "node ./Build/validate-cdn-conf.js"
|
||||
},
|
||||
"build": {
|
||||
"dependencies": [
|
||||
"build:anti-bogus-domain",
|
||||
"build:apple-cdn",
|
||||
"build:cdn-conf",
|
||||
"build:reject-domainset",
|
||||
"build:telegram-cidr",
|
||||
"build:chn-cidr",
|
||||
"build:index-html",
|
||||
"validate:cdn-conf"
|
||||
]
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/SukkaW/Surge.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@sukka/listdir": "^0.2.0",
|
||||
"@vercel/fetch-retry": "^5.1.3",
|
||||
"ci-info": "^3.5.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"piscina": "^3.2.0",
|
||||
"psl": "^1.9.0",
|
||||
"table": "^6.8.0",
|
||||
"undici": "5.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"wireit": "^0.7.2"
|
||||
}
|
||||
}
|
||||
477
pnpm-lock.yaml
generated
477
pnpm-lock.yaml
generated
@@ -1,477 +0,0 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@sukka/listdir': ^0.2.0
|
||||
'@vercel/fetch-retry': ^5.1.3
|
||||
ci-info: ^3.5.0
|
||||
picocolors: ^1.0.0
|
||||
piscina: ^3.2.0
|
||||
psl: ^1.9.0
|
||||
table: ^6.8.0
|
||||
undici: 5.11.0
|
||||
wireit: ^0.7.2
|
||||
|
||||
dependencies:
|
||||
'@sukka/listdir': 0.2.0
|
||||
'@vercel/fetch-retry': 5.1.3
|
||||
ci-info: 3.5.0
|
||||
picocolors: 1.0.0
|
||||
piscina: 3.2.0
|
||||
psl: 1.9.0
|
||||
table: 6.8.0
|
||||
undici: 5.11.0
|
||||
|
||||
devDependencies:
|
||||
wireit: 0.7.2
|
||||
|
||||
packages:
|
||||
|
||||
/@assemblyscript/loader/0.10.1:
|
||||
resolution: {integrity: sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==}
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.scandir/2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
run-parallel: 1.2.0
|
||||
dev: true
|
||||
|
||||
/@nodelib/fs.stat/2.0.5:
|
||||
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: true
|
||||
|
||||
/@nodelib/fs.walk/1.2.8:
|
||||
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.13.0
|
||||
dev: true
|
||||
|
||||
/@sukka/listdir/0.2.0:
|
||||
resolution: {integrity: sha512-UyVirNhAOXKwjiDehjUaGtpfk0QwNHyiXrlLb/FmWMtI+BGhaEvB9MypSfEAtiiMI3g6QTfG38ayNAorEuz5ow==}
|
||||
dev: false
|
||||
|
||||
/@vercel/fetch-retry/5.1.3:
|
||||
resolution: {integrity: sha512-UIbFc4VsEZHOr6dWuE+kxY4NxnOLXFMCWm0fSKRRHUEtrIzaJLzHpWk2QskCXTSzFgFvhkLAvSrBK2XZg7NSzg==}
|
||||
peerDependencies:
|
||||
node-fetch: ^2.6.7
|
||||
dependencies:
|
||||
async-retry: 1.3.3
|
||||
debug: 4.3.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/ajv/8.8.2:
|
||||
resolution: {integrity: sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==}
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
uri-js: 4.4.1
|
||||
dev: false
|
||||
|
||||
/ansi-regex/5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/ansi-styles/4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
dev: false
|
||||
|
||||
/anymatch/3.1.2:
|
||||
resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
normalize-path: 3.0.0
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/astral-regex/2.0.0:
|
||||
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/async-retry/1.3.3:
|
||||
resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==}
|
||||
dependencies:
|
||||
retry: 0.13.1
|
||||
dev: false
|
||||
|
||||
/base64-js/1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: false
|
||||
|
||||
/binary-extensions/2.2.0:
|
||||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/braces/3.0.2:
|
||||
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
fill-range: 7.0.1
|
||||
dev: true
|
||||
|
||||
/busboy/1.6.0:
|
||||
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
|
||||
engines: {node: '>=10.16.0'}
|
||||
dependencies:
|
||||
streamsearch: 1.1.0
|
||||
dev: false
|
||||
|
||||
/chokidar/3.5.3:
|
||||
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
dependencies:
|
||||
anymatch: 3.1.2
|
||||
braces: 3.0.2
|
||||
glob-parent: 5.1.2
|
||||
is-binary-path: 2.1.0
|
||||
is-glob: 4.0.3
|
||||
normalize-path: 3.0.0
|
||||
readdirp: 3.6.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: true
|
||||
|
||||
/ci-info/3.5.0:
|
||||
resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==}
|
||||
dev: false
|
||||
|
||||
/color-convert/2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: false
|
||||
|
||||
/color-name/1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: false
|
||||
|
||||
/debug/4.3.4:
|
||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: false
|
||||
|
||||
/emoji-regex/8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
dev: false
|
||||
|
||||
/eventemitter-asyncresource/1.0.0:
|
||||
resolution: {integrity: sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==}
|
||||
dev: false
|
||||
|
||||
/fast-deep-equal/3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: false
|
||||
|
||||
/fast-glob/3.2.11:
|
||||
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
dependencies:
|
||||
'@nodelib/fs.stat': 2.0.5
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
glob-parent: 5.1.2
|
||||
merge2: 1.4.1
|
||||
micromatch: 4.0.5
|
||||
dev: true
|
||||
|
||||
/fastq/1.13.0:
|
||||
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
|
||||
dependencies:
|
||||
reusify: 1.0.4
|
||||
dev: true
|
||||
|
||||
/fill-range/7.0.1:
|
||||
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
dev: true
|
||||
|
||||
/fsevents/2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/glob-parent/5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
dev: true
|
||||
|
||||
/graceful-fs/4.2.10:
|
||||
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
|
||||
dev: true
|
||||
|
||||
/hdr-histogram-js/2.0.1:
|
||||
resolution: {integrity: sha512-uPZxl1dAFnjUFHWLZmt93vUUvtHeaBay9nVNHu38SdOjMSF/4KqJUqa1Seuj08ptU1rEb6AHvB41X8n/zFZ74Q==}
|
||||
dependencies:
|
||||
'@assemblyscript/loader': 0.10.1
|
||||
base64-js: 1.5.1
|
||||
pako: 1.0.11
|
||||
dev: false
|
||||
|
||||
/hdr-histogram-percentiles-obj/3.0.0:
|
||||
resolution: {integrity: sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==}
|
||||
dev: false
|
||||
|
||||
/is-binary-path/2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
binary-extensions: 2.2.0
|
||||
dev: true
|
||||
|
||||
/is-extglob/2.1.1:
|
||||
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/is-fullwidth-code-point/3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
dev: false
|
||||
|
||||
/is-glob/4.0.3:
|
||||
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
is-extglob: 2.1.1
|
||||
dev: true
|
||||
|
||||
/is-number/7.0.0:
|
||||
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
dev: true
|
||||
|
||||
/json-schema-traverse/1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
dev: false
|
||||
|
||||
/jsonc-parser/3.0.0:
|
||||
resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==}
|
||||
dev: true
|
||||
|
||||
/lodash.truncate/4.4.2:
|
||||
resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
|
||||
dev: false
|
||||
|
||||
/merge2/1.4.1:
|
||||
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
|
||||
engines: {node: '>= 8'}
|
||||
dev: true
|
||||
|
||||
/micromatch/4.0.5:
|
||||
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
|
||||
engines: {node: '>=8.6'}
|
||||
dependencies:
|
||||
braces: 3.0.2
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/ms/2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: false
|
||||
|
||||
/nice-napi/1.0.2:
|
||||
resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==}
|
||||
os: ['!win32']
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-addon-api: 3.2.1
|
||||
node-gyp-build: 4.3.0
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/node-addon-api/3.2.1:
|
||||
resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==}
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/node-gyp-build/4.3.0:
|
||||
resolution: {integrity: sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/normalize-path/3.0.0:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/pako/1.0.11:
|
||||
resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==}
|
||||
dev: false
|
||||
|
||||
/picocolors/1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
dev: false
|
||||
|
||||
/picomatch/2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
dev: true
|
||||
|
||||
/piscina/3.2.0:
|
||||
resolution: {integrity: sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==}
|
||||
dependencies:
|
||||
eventemitter-asyncresource: 1.0.0
|
||||
hdr-histogram-js: 2.0.1
|
||||
hdr-histogram-percentiles-obj: 3.0.0
|
||||
optionalDependencies:
|
||||
nice-napi: 1.0.2
|
||||
dev: false
|
||||
|
||||
/proper-lockfile/4.1.2:
|
||||
resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==}
|
||||
dependencies:
|
||||
graceful-fs: 4.2.10
|
||||
retry: 0.12.0
|
||||
signal-exit: 3.0.7
|
||||
dev: true
|
||||
|
||||
/psl/1.9.0:
|
||||
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
|
||||
dev: false
|
||||
|
||||
/punycode/2.1.1:
|
||||
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/queue-microtask/1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
dev: true
|
||||
|
||||
/readdirp/3.6.0:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
dev: true
|
||||
|
||||
/require-from-string/2.0.2:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/retry/0.12.0:
|
||||
resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
|
||||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/retry/0.13.1:
|
||||
resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
|
||||
engines: {node: '>= 4'}
|
||||
dev: false
|
||||
|
||||
/reusify/1.0.4:
|
||||
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/run-parallel/1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
dev: true
|
||||
|
||||
/signal-exit/3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
dev: true
|
||||
|
||||
/slice-ansi/4.0.0:
|
||||
resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
astral-regex: 2.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
dev: false
|
||||
|
||||
/streamsearch/1.1.0:
|
||||
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dev: false
|
||||
|
||||
/string-width/4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.1
|
||||
dev: false
|
||||
|
||||
/strip-ansi/6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
dev: false
|
||||
|
||||
/table/6.8.0:
|
||||
resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
dependencies:
|
||||
ajv: 8.8.2
|
||||
lodash.truncate: 4.4.2
|
||||
slice-ansi: 4.0.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
dev: false
|
||||
|
||||
/to-regex-range/5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
engines: {node: '>=8.0'}
|
||||
dependencies:
|
||||
is-number: 7.0.0
|
||||
dev: true
|
||||
|
||||
/undici/5.11.0:
|
||||
resolution: {integrity: sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw==}
|
||||
engines: {node: '>=12.18'}
|
||||
dependencies:
|
||||
busboy: 1.6.0
|
||||
dev: false
|
||||
|
||||
/uri-js/4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
dependencies:
|
||||
punycode: 2.1.1
|
||||
dev: false
|
||||
|
||||
/wireit/0.7.2:
|
||||
resolution: {integrity: sha512-Zjq50QH5hguk64hXfJmJJpLGgi8TUy7780w0u2VXK325qWxJtw1fP6HhOYcdjTWeoYLWQDDkTytQ119y/UMseg==}
|
||||
engines: {node: '>=14.14.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
braces: 3.0.2
|
||||
chokidar: 3.5.3
|
||||
fast-glob: 3.2.11
|
||||
jsonc-parser: 3.0.0
|
||||
proper-lockfile: 4.1.2
|
||||
dev: true
|
||||
Reference in New Issue
Block a user