mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-23 18:03:44 +03:00
refactored
This commit is contained in:
parent
2000a3020d
commit
00d23d0292
|
@ -44,4 +44,34 @@ blocked-ips-switch.js: 30 bytes, 1339607 ns, Missed: 84 bytes,
|
|||
blocked-ips-binary.js: 31 bytes, 3552007 ns, Missed: 76 bytes, 603872 ns
|
||||
======================
|
||||
blocked-hosts-binary-trie.js: 364 bytes, 27134555ns, Missed: 218 bytes, 725467 ns
|
||||
blocked-hosts-simple-trie.js: 364 bytes, 4085395 ns, Missed: 219 bytes, 649011 ns
|
||||
blocked-hosts-simple-trie.js: 364 bytes, 4085395 ns, Missed: 219 bytes, 649011 ns
|
||||
======================
|
||||
blocked-hosts-plain-switch.js: 69 bytes, 2850095 ns, Missed: 96 bytes, 590933 ns
|
||||
blocked-hosts-switch.js: 93 bytes, 854636 ns, Missed: 77 bytes, 597410 ns
|
||||
blocked-hosts-reversed-binary.js: 109 bytes, 3710108 ns, Missed: 96 bytes, 604745 ns
|
||||
blocked-hosts-hash.js: 351 bytes, 5112411 ns, Missed: 203 bytes, 605303 ns
|
||||
blocked-hosts-binary.js: 355 bytes, 3691874 ns, Missed: 207 bytes, 615506 ns
|
||||
|
||||
blocked-ips-binary.js: 33 bytes, 3558958 ns, Missed: 81 bytes, 607783 ns
|
||||
blocked-ips-indexOf.js: 35 bytes, 4832252 ns, Missed: 77 bytes, 593958 ns
|
||||
blocked-ips-switch.js: 36 bytes, 1341637 ns, Missed: 76 bytes, 613332 ns
|
||||
======================
|
||||
blocked-hosts-binary.js: 356 bytes, 3763269 ns, Missed: 211 bytes, 595469 ns
|
||||
blocked-hosts-plain-switch.js: 364 bytes, 2865722 ns, Missed: 223 bytes, 597233 ns
|
||||
blocked-hosts-reversed-binary.js: 106 bytes, 3680757 ns, Missed: 96 bytes, 604607 ns
|
||||
blocked-hosts-switch.js: 93 bytes, 865423 ns, Missed: 81 bytes, 606328 ns
|
||||
blocked-hosts-hash.js: 347 bytes, 5163575 ns, Missed: 207 bytes, 607421 ns
|
||||
|
||||
blocked-ips-indexOf.js: 33 bytes, 4845498 ns, Missed: 77 bytes, 594833 ns
|
||||
blocked-ips-switch.js: 35 bytes, 1345531 ns, Missed: 77 bytes, 601800 ns
|
||||
blocked-ips-binary.js: 38 bytes, 3575806 ns, Missed: 80 bytes, 608611 ns
|
||||
======================
|
||||
blocked-hosts-reversed-binary.js: 109 bytes, 3704594 ns, Missed: 96 bytes, 602820 ns
|
||||
blocked-hosts-binary.js: 351 bytes, 3718253 ns, Missed: 210 bytes, 605188 ns
|
||||
blocked-hosts-plain-switch.js: 367 bytes, 2874843 ns, Missed: 88 bytes, 607200 ns
|
||||
blocked-hosts-hash.js: 347 bytes, 5062512 ns, Missed: 207 bytes, 609278 ns
|
||||
blocked-hosts-switch.js: 88 bytes, 894410 ns, Missed: 77 bytes, 614169 ns
|
||||
|
||||
blocked-ips-switch.js: 37 bytes, 1348111 ns, Missed: 72 bytes, 597439 ns
|
||||
blocked-ips-indexOf.js: 35 bytes, 4853437 ns, Missed: 72 bytes, 599850 ns
|
||||
blocked-ips-binary.js: 31 bytes, 3542401 ns, Missed: 77 bytes, 602958 ns
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
414
generate-PACs.js
414
generate-PACs.js
|
@ -1,414 +0,0 @@
|
|||
var fs = require('fs');
|
||||
|
||||
var input = fs.readFileSync('dump.csv').toString();
|
||||
var outputDir = 'generated-PACs';
|
||||
|
||||
try {
|
||||
fs.mkdirSync( outputDir );
|
||||
} catch(e) {
|
||||
if ( e.code != 'EEXIST' ) throw e;
|
||||
}
|
||||
|
||||
var punycode = require('punycode')
|
||||
|
||||
/*
|
||||
CVS Format:
|
||||
|
||||
IP(s);host(s);URL(s);organization(s);reason;yyyy-mm-dd
|
||||
|
||||
* multiple values are joind by " | "
|
||||
* url may have wierd protocol, e.g.: Newcamd525://
|
||||
|
||||
*/
|
||||
|
||||
var columnsSep = ';';
|
||||
var valuesSep = /\s*\|\s*/g;
|
||||
|
||||
var ips = [], hosts = [], urls = [], orgs = [], date, reason;
|
||||
|
||||
for(var line of input.trim().split(/\r?\n/g).slice(1)) {
|
||||
var values = line.split( columnsSep );
|
||||
var newIps = values.shift().split( valuesSep );
|
||||
var newHosts = values.shift().split( valuesSep ).map( punycode.toASCII ).map( host => host.replace(/\.+$/g) );
|
||||
var newUrls = values.shift().split( valuesSep );
|
||||
var newOrgs = values.shift().split( valuesSep );
|
||||
var newDate = values.pop();
|
||||
var newReason = values.join(';');
|
||||
ips.push.apply(ips, newIps);
|
||||
hosts.push.apply(hosts, newHosts);
|
||||
}
|
||||
|
||||
function toHash(arr) {
|
||||
var res = {};
|
||||
arr.forEach( el => res[el] = true );
|
||||
return res;
|
||||
}
|
||||
|
||||
var ipsHash = toHash(ips);
|
||||
var hostsHash = toHash(hosts);
|
||||
|
||||
// Remove duplicates and sort.
|
||||
var ips = Object.keys(ipsHash).sort();
|
||||
var hosts = Object.keys(hostsHash).sort();
|
||||
|
||||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return IFPROXY() ? viaProxy : 'DIRECT';
|
||||
}
|
||||
|
||||
var pacTemplate = FindProxyForURL.toString();
|
||||
|
||||
function stringifyCall() {
|
||||
var fun = arguments[0];
|
||||
var args = [].slice.call( arguments, 1 )
|
||||
.map( a => typeof a !== 'string' ? JSON.stringify(a) : a ).join(', ');
|
||||
return '('+fun+')('+args+')';
|
||||
}
|
||||
|
||||
function produceOutput() {
|
||||
var args = [].slice.call( arguments )
|
||||
var scriptName = args.shift();
|
||||
|
||||
var script = pacTemplate
|
||||
.replace( 'IFPROXY()', stringifyCall.apply(this, args) );
|
||||
fs.writeFileSync(outputDir +'/'+ scriptName +'.js', script);
|
||||
}
|
||||
|
||||
// BLOCKED IPS ARRAY
|
||||
|
||||
function ifProxyByIp(host, blockedIpsArray) {
|
||||
|
||||
// Internet Explorer
|
||||
if (!Array.prototype.indexOf)
|
||||
Array.prototype.indexOf = function(obj, start) {
|
||||
for (var i = (start || 0), j = this.length; i < j; i++)
|
||||
if (this[i] === obj) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return blockedIpsArray.indexOf( dnsResolve(host) ) !== -1
|
||||
}
|
||||
|
||||
produceOutput('blocked-ips-indexOf', ifProxyByIp, 'host', ips);
|
||||
|
||||
// BLOCKED IPS SWITCH
|
||||
|
||||
function ifProxyBySwitch(host) {
|
||||
switch( dnsResolve(host) ) {
|
||||
/*{CASES}*/
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var cases = ips.map( ip => 'case "'+ip+'":' ).join('\n') +'\nreturn true;';
|
||||
var ifProxySwitchStr = ifProxyBySwitch.toString().replace('/*{CASES}*/', cases);
|
||||
|
||||
produceOutput('blocked-ips-switch', ifProxySwitchStr, 'host' );
|
||||
|
||||
// BLOCKED IPS BINARY
|
||||
|
||||
function ifBinaryFound(target, sortedArray) {
|
||||
var istart = 0;
|
||||
var iend = sortedArray.length - 1;
|
||||
|
||||
while (istart < iend) {
|
||||
var imid = istart + Math.floor( (iend - istart)*0.5 );
|
||||
if (target > sortedArray[imid])
|
||||
istart = imid + 1;
|
||||
else
|
||||
iend = imid;
|
||||
}
|
||||
|
||||
return target === sortedArray[iend];
|
||||
}
|
||||
|
||||
produceOutput('blocked-ips-binary', ifBinaryFound, 'dnsResolve(host)', ips);
|
||||
|
||||
// BLOCKED HOSTS BINARY
|
||||
produceOutput('blocked-hosts-binary', ifBinaryFound, 'host', hosts);
|
||||
|
||||
// REVERSED BINARY
|
||||
|
||||
var reverse = str => str.split('').reverse().join('');
|
||||
var reversedHosts = hosts.map( reverse ).sort();
|
||||
|
||||
function ifReversedBinaryFound(host, sortedArray) {
|
||||
target = host.split('').reverse().join('');
|
||||
var istart = 0;
|
||||
var iend = sortedArray.length - 1;
|
||||
|
||||
while (istart < iend) {
|
||||
var imid = istart + Math.floor( (iend - istart)*0.5 );
|
||||
if (target > sortedArray[imid])
|
||||
istart = imid + 1;
|
||||
else
|
||||
iend = imid;
|
||||
}
|
||||
return dnsDomainIs( host, sortedArray[iend].split('').reverse().join('') );
|
||||
}
|
||||
|
||||
produceOutput('blocked-hosts-reversed-binary', ifReversedBinaryFound, 'host', reversedHosts);
|
||||
|
||||
// REVERSED HOSTS SWITCH
|
||||
|
||||
function populateTrie(trie, doms) {
|
||||
|
||||
var dom = doms.pop();
|
||||
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
|
||||
trie[''] = trie[''] || [];
|
||||
trie[''].push( dom )
|
||||
return trie;
|
||||
}
|
||||
|
||||
if (trie[''] && trie[''].indexOf(dom) !== -1) // Subdomain of a blocked domain.
|
||||
return trie;
|
||||
|
||||
trie[dom] = trie[dom] || {};
|
||||
|
||||
populateTrie( trie[dom], doms );
|
||||
return trie;
|
||||
}
|
||||
|
||||
var trie = {};
|
||||
for(var host of hosts) {
|
||||
var doms = host.split('.');
|
||||
populateTrie(trie, doms);
|
||||
}
|
||||
|
||||
function trieToSwitch(trie, indent) {
|
||||
var _indent = indent || '';
|
||||
var indent = _indent + ' ';
|
||||
var keys = Object.keys(trie).sort();
|
||||
|
||||
if (!trie[''] && keys.length === 1) {
|
||||
var key = keys[0];
|
||||
return _indent + 'if (doms.pop() === "'+key+'")\n'+ trieToSwitch(trie[key], indent);
|
||||
}
|
||||
|
||||
var cases = '';
|
||||
if (trie['']) {
|
||||
var values = trie[''].sort();
|
||||
|
||||
if (values.length === 1 && keys.length === 1)
|
||||
return _indent + 'return doms.pop() === "'+values[0]+'";\n';
|
||||
|
||||
cases =
|
||||
values.filter( v => v ).map( val => indent +'case "'+val+'":\n' ).join('') + indent +' return true;\n';
|
||||
|
||||
delete trie[''];
|
||||
keys = Object.keys(trie).sort();
|
||||
}
|
||||
|
||||
cases += keys.filter( k => k ).map(
|
||||
key => {
|
||||
var tmp = trieToSwitch( trie[key], indent+' ');
|
||||
if (!/^\s*return/.test(tmp))
|
||||
tmp += indent+' break;\n';
|
||||
|
||||
return indent +'case "'+key+'":\n' +tmp;
|
||||
}
|
||||
).join('');
|
||||
|
||||
return ''
|
||||
+ _indent +'switch( doms.pop() ) {\n'
|
||||
+ cases
|
||||
+ _indent +'}\n';
|
||||
}
|
||||
|
||||
function ifProxyByTrie(host) {
|
||||
//SWITCH
|
||||
return false;
|
||||
}
|
||||
|
||||
var ifProxyByTrieStr = ifProxyByTrie.toString().replace('//SWITCH', trieToSwitch(trie, ' '));
|
||||
|
||||
produceOutput('blocked-hosts-switch', ifProxyByTrieStr, 'host' );
|
||||
|
||||
/* REVERSED HOSTS BINARY TRIE
|
||||
|
||||
function populateBinTrie(trie, doms) {
|
||||
var dom = doms.pop();
|
||||
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
|
||||
trie[dom] = 'blocked';
|
||||
return trie;
|
||||
}
|
||||
|
||||
if (trie[dom] === 'blocked') // Subdomain of a blocked domain.
|
||||
return trie;
|
||||
|
||||
trie[dom] = trie[dom] || {};
|
||||
populateBinTrie( trie[dom], doms );
|
||||
return trie;
|
||||
}
|
||||
|
||||
var trie = {};
|
||||
for(var host of hosts) {
|
||||
var doms = host.split('.');
|
||||
populateBinTrie(trie, doms);
|
||||
}
|
||||
|
||||
function trie2sorted(trie) {
|
||||
if (trie === 'blocked')
|
||||
return trie;
|
||||
|
||||
var keys = Object.keys(trie).sort();
|
||||
return keys.map( key => trie[key] !== 'blocked' ? [ key, trie2sorted( trie[key] ) ] : [key] );
|
||||
}
|
||||
|
||||
var sortedTrie = trie2sorted(trie);
|
||||
|
||||
function ifProxyByBinTrie(host, sortedTrie) {
|
||||
|
||||
var doms = host.split('.');
|
||||
|
||||
function ifBinaryBlocked(sortedTrie) {
|
||||
var target = doms.pop();
|
||||
if (!target)
|
||||
return false;
|
||||
|
||||
var istart = 0;
|
||||
var iend = sortedTrie.length - 1;
|
||||
|
||||
while (istart < iend) {
|
||||
var imid = istart + Math.floor( (iend - istart)*0.5 );
|
||||
if (target > sortedTrie[imid][0])
|
||||
istart = imid + 1;
|
||||
else
|
||||
iend = imid;
|
||||
}
|
||||
|
||||
if (target !== sortedTrie[iend][0])
|
||||
return false;
|
||||
|
||||
return sortedTrie[iend].length < 2 ? true : ifBinaryBlocked( sortedTrie[iend][1] );
|
||||
}
|
||||
|
||||
return ifBinaryBlocked(sortedTrie)
|
||||
}
|
||||
|
||||
produceOutput('blocked-hosts-binary-trie', ifProxyByBinTrie, 'host', sortedTrie);
|
||||
|
||||
*/
|
||||
|
||||
// BLOCKED HOSTS PLAIN SWITCH
|
||||
|
||||
function ifProxyByPlainSwitch(host) {
|
||||
|
||||
function ifBlocked(host) {
|
||||
switch( host ) {
|
||||
//CASES
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var doms = host.split('.');
|
||||
|
||||
for( var endi = doms.length-1; endi >= 0; --endi )
|
||||
if (ifBlocked( doms.slice( endi ).join('.') ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var cases = hosts.map( host => 'case "'+host+'":' ).join('\n') +'\nreturn true;';
|
||||
var tmp = ifProxyByPlainSwitch.toString().replace('//CASES', cases);
|
||||
|
||||
produceOutput( 'blocked-hosts-plain-switch', tmp, 'host' );
|
||||
|
||||
|
||||
// SIMPLY TRIE
|
||||
|
||||
function populateSimpleTrie(trie, letters) {
|
||||
|
||||
if (!letters.length || !trie)
|
||||
return trie;
|
||||
|
||||
var letter = letters.shift();
|
||||
|
||||
if (!letters.length) {
|
||||
trie[letter] = ['', false];
|
||||
return trie;
|
||||
}
|
||||
|
||||
if (trie[letter] === ['', false]) // Subdomain of a blocked domain.
|
||||
return trie;
|
||||
|
||||
if (!trie[letter]) {
|
||||
trie[letter] = [letters.join(''), false]
|
||||
return trie;
|
||||
}
|
||||
|
||||
var arr = trie[letter];
|
||||
var link = arr[0].split('');
|
||||
var linkTrie = arr[1];
|
||||
|
||||
function commonPrefix(wa, wb) {
|
||||
var len = Math.min(wa.length, wb.length);
|
||||
var i = -1;
|
||||
while(++i < len)
|
||||
if (wa[i] !== wb[i])
|
||||
break;
|
||||
return wa.slice(0, i)
|
||||
}
|
||||
|
||||
var prefix = commonPrefix(link, letters);
|
||||
|
||||
var suffixLetters = letters.slice(prefix.length);
|
||||
var suffixLink = link.slice(prefix.length);
|
||||
|
||||
var newTrie = {};
|
||||
if (!suffixLink.length)
|
||||
var newTrie = linkTrie;
|
||||
if (!suffixLetters.length)
|
||||
var newTrie = false;
|
||||
|
||||
if (newTrie) {
|
||||
newTrie = populateSimpleTrie( newTrie, suffixLetters );
|
||||
newTrie = populateSimpleTrie( newTrie, suffixLink );
|
||||
}
|
||||
trie[letter] = [prefix.join(''), newTrie];
|
||||
|
||||
return trie;
|
||||
}
|
||||
|
||||
var simpleTrie = {};
|
||||
for(var host of hosts)
|
||||
populateSimpleTrie(simpleTrie, host.split('').reverse());
|
||||
|
||||
function ifProxyBySimpleTrie(host, simpleTrie) {
|
||||
var letters = host.split('').reverse();
|
||||
while(letters.length) {
|
||||
var letter = letters.shift();
|
||||
var arr = simpleTrie[letter];
|
||||
var link = arr[0];
|
||||
|
||||
if (link.length > letters.length)
|
||||
return false;
|
||||
|
||||
for( var i=0; i < link.length; ++i )
|
||||
if ( letters[i] !== link.charAt(i) )
|
||||
return false;
|
||||
|
||||
letters = letters.slice(link.length);
|
||||
simpleTrie = arr[1];
|
||||
if (!simpleTrie)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
produceOutput('blocked-hosts-simple-trie', ifProxyBySimpleTrie, 'host', simpleTrie);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Can't render this file because it is too large.
|
29
pac-generator/generate-PACs.js
Executable file
29
pac-generator/generate-PACs.js
Executable file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
var generator = require('./pac-generator');
|
||||
|
||||
var normalizedPath = require('path').join(__dirname, 'src');
|
||||
|
||||
var outputDir = './generated-PACs';
|
||||
|
||||
var fs = require('fs')
|
||||
try {
|
||||
fs.mkdirSync( outputDir );
|
||||
} catch(e) {
|
||||
if ( e.code != 'EEXIST' ) throw e;
|
||||
}
|
||||
|
||||
fs.readdirSync( normalizedPath )
|
||||
.filter( file => file.startsWith('blocked-') )
|
||||
.forEach( file =>
|
||||
require('./src/'+ file)(
|
||||
generator.hosts,
|
||||
generator.ips,
|
||||
generator,
|
||||
function generatePac() {
|
||||
var args = [].slice.call( arguments );
|
||||
args.unshift( outputDir +'/'+ file )
|
||||
generator.writeOutputToFile.apply( generator, args );
|
||||
}
|
||||
)
|
||||
);
|
File diff suppressed because one or more lines are too long
23
pac-generator/generated-PACs/blocked-hosts-hash.js
Executable file
23
pac-generator/generated-PACs/blocked-hosts-hash.js
Executable file
File diff suppressed because one or more lines are too long
|
@ -1,24 +1,24 @@
|
|||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyByPlainSwitch(host) {
|
||||
|
||||
function ifBlocked(host) {
|
||||
switch( host ) {
|
||||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyByPlainSwitch(host) {
|
||||
|
||||
function ifBlocked(host) {
|
||||
switch( host ) {
|
||||
case "03magnet.ru":
|
||||
case "0chan.cc":
|
||||
case "1-kino.com":
|
||||
|
@ -9842,16 +9842,16 @@ case "zubromix.com":
|
|||
case "zubrrotzdg2m2uy7.onion.to":
|
||||
case "zuu9ieth.cserver.tv":
|
||||
case "zz.jofra.biz":
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var doms = host.split('.');
|
||||
|
||||
for( var endi = doms.length-1; endi >= 0; --endi )
|
||||
if (ifBlocked( doms.slice( endi ).join('.') ))
|
||||
return true;
|
||||
return false;
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var doms = host.split('.');
|
||||
|
||||
for( var endi = doms.length-1; endi >= 0; --endi )
|
||||
if (ifBlocked( doms.slice( endi ).join('.') ))
|
||||
return true;
|
||||
return false;
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
}
|
32
pac-generator/generated-PACs/blocked-hosts-reversed-binary.js
Executable file
32
pac-generator/generated-PACs/blocked-hosts-reversed-binary.js
Executable file
File diff suppressed because one or more lines are too long
|
@ -1,21 +1,22 @@
|
|||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyByTrie(host) {
|
||||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyByTrie(host) {
|
||||
var doms = host.split('.');
|
||||
switch( doms.pop() ) {
|
||||
case "102":
|
||||
if (doms.pop() === "120")
|
||||
|
@ -10124,7 +10125,7 @@ function FindProxyForURL(url, host) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
|
||||
return false;
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
}
|
File diff suppressed because one or more lines are too long
30
pac-generator/generated-PACs/blocked-ips-indexOf.js
Executable file
30
pac-generator/generated-PACs/blocked-ips-indexOf.js
Executable file
File diff suppressed because one or more lines are too long
|
@ -1,22 +1,22 @@
|
|||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyBySwitch(host) {
|
||||
switch( dnsResolve(host) ) {
|
||||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return (function ifProxyBySwitch(host) {
|
||||
switch( dnsResolve(host) ) {
|
||||
case "101.1.29.82":
|
||||
case "103.21.58.156":
|
||||
case "103.240.151.25":
|
||||
|
@ -9540,9 +9540,8 @@ case "98.139.135.198":
|
|||
case "98.142.213.26":
|
||||
case "99.192.182.57":
|
||||
case "99.198.117.212":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
})(host) ? viaProxy : 'DIRECT';
|
||||
}
|
95
pac-generator/pac-generator.js
Executable file
95
pac-generator/pac-generator.js
Executable file
|
@ -0,0 +1,95 @@
|
|||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var input = fs.readFileSync('dump.csv').toString();
|
||||
|
||||
var punycode = require('punycode')
|
||||
|
||||
/*
|
||||
CVS Format:
|
||||
|
||||
IP(s);host(s);URL(s);organization(s);reason;yyyy-mm-dd
|
||||
|
||||
* multiple values are joind by " | "
|
||||
* url may have wierd protocol, e.g.: Newcamd525://
|
||||
|
||||
*/
|
||||
|
||||
var columnsSep = ';';
|
||||
var valuesSep = /\s*\|\s*/g;
|
||||
|
||||
var ips = [], hosts = [], urls = [], orgs = [], date, reason;
|
||||
|
||||
for(var line of input.trim().split(/\r?\n/g).slice(1)) {
|
||||
var values = line.split( columnsSep );
|
||||
var newIps = values.shift().split( valuesSep );
|
||||
var newHosts = values.shift().split( valuesSep ).map( punycode.toASCII ).map( host => host.replace(/\.+$/g) );
|
||||
var newUrls = values.shift().split( valuesSep );
|
||||
var newOrgs = values.shift().split( valuesSep );
|
||||
var newDate = values.pop();
|
||||
var newReason = values.join(';');
|
||||
ips.push.apply(ips, newIps);
|
||||
hosts.push.apply(hosts, newHosts);
|
||||
}
|
||||
|
||||
function toHash(arr) {
|
||||
var res = {};
|
||||
arr.forEach( el => res[el] = true );
|
||||
return res;
|
||||
}
|
||||
|
||||
var ipsHash = toHash(ips);
|
||||
var hostsHash = toHash(hosts);
|
||||
|
||||
// Remove duplicates and sort.
|
||||
var ips = Object.keys(ipsHash).sort();
|
||||
var hosts = Object.keys(hostsHash).sort();
|
||||
|
||||
function FindProxyForURL(url, host) {
|
||||
// ProstoVPN.AntiZapret PAC-ip File
|
||||
// Generated on Sun Nov 22 10:12:29 MSK 2015
|
||||
|
||||
// The whole PAC script is reevaluated on each call of this function.
|
||||
|
||||
host = host.replace(/\.+$/).toLowerCase(); // E.g. WinHTTP may be nasty.
|
||||
|
||||
// HTTPS proxy is a HTTP proxy over SSL. It is NOT CONNECT proxy!
|
||||
// Supported only in Chrome and Firefox.
|
||||
// http://www.chromium.org/developers/design-documents/secure-web-proxy
|
||||
// This is to bypass FULL DPI
|
||||
var isIE = /*@cc_on!@*/!1;
|
||||
var viaProxy = isIE
|
||||
? 'PROXY proxy.antizapret.prostovpn.org:3128; DIRECT'
|
||||
: 'HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT';
|
||||
|
||||
return IFPROXY() ? viaProxy : 'DIRECT';
|
||||
}
|
||||
|
||||
var pacTemplate = FindProxyForURL.toString();
|
||||
|
||||
function stringifyCall() {
|
||||
var args = [].slice.call( arguments );
|
||||
var fun = args.shift();
|
||||
var args = args
|
||||
.map( a => typeof a !== 'string' ? JSON.stringify(a) : a ).join(', ');
|
||||
return '('+fun+')('+args+')';
|
||||
}
|
||||
|
||||
function ifProxy2pac() {
|
||||
return pacTemplate.replace( 'IFPROXY()', stringifyCall.apply(this, arguments) );
|
||||
}
|
||||
|
||||
function writeOutputToFile() {
|
||||
var args = [].slice.call( arguments );
|
||||
var scriptPath = args.shift();
|
||||
var pac = ifProxy2pac.apply(this, args);
|
||||
fs.writeFileSync( scriptPath, pac);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hosts: hosts,
|
||||
ips: ips,
|
||||
stringifyCall: stringifyCall,
|
||||
writeOutputToFile: writeOutputToFile,
|
||||
}
|
15
pac-generator/package.json
Executable file
15
pac-generator/package.json
Executable file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "subjective-good-is-evil",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node generate-PACs.js",
|
||||
"serve": "http-server generated-PACs"
|
||||
},
|
||||
"author": "ilyaigpetrov",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"http-server": "^0.8.5"
|
||||
}
|
||||
}
|
85
pac-generator/src/_blocked-hosts-simple-trie.js
Executable file
85
pac-generator/src/_blocked-hosts-simple-trie.js
Executable file
|
@ -0,0 +1,85 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
function populateSimpleTrie(trie, letters) {
|
||||
|
||||
if (!letters.length || !trie)
|
||||
return trie;
|
||||
|
||||
var letter = letters.shift();
|
||||
|
||||
if (!letters.length) {
|
||||
trie[letter] = ['', false];
|
||||
return trie;
|
||||
}
|
||||
|
||||
if (trie[letter] === ['', false]) // Subdomain of a blocked domain.
|
||||
return trie;
|
||||
|
||||
if (!trie[letter]) {
|
||||
trie[letter] = [letters.join(''), false]
|
||||
return trie;
|
||||
}
|
||||
|
||||
var arr = trie[letter];
|
||||
var link = arr[0].split('');
|
||||
var linkTrie = arr[1];
|
||||
|
||||
function commonPrefix(wa, wb) {
|
||||
var len = Math.min(wa.length, wb.length);
|
||||
var i = -1;
|
||||
while(++i < len)
|
||||
if (wa[i] !== wb[i])
|
||||
break;
|
||||
return wa.slice(0, i)
|
||||
}
|
||||
|
||||
var prefix = commonPrefix(link, letters);
|
||||
|
||||
var suffixLetters = letters.slice(prefix.length);
|
||||
var suffixLink = link.slice(prefix.length);
|
||||
|
||||
var newTrie = {};
|
||||
if (!suffixLink.length)
|
||||
var newTrie = linkTrie;
|
||||
if (!suffixLetters.length)
|
||||
var newTrie = false;
|
||||
|
||||
if (newTrie) {
|
||||
newTrie = populateSimpleTrie( newTrie, suffixLetters );
|
||||
newTrie = populateSimpleTrie( newTrie, suffixLink );
|
||||
}
|
||||
trie[letter] = [prefix.join(''), newTrie];
|
||||
|
||||
return trie;
|
||||
}
|
||||
|
||||
var simpleTrie = {};
|
||||
for(var host of hosts)
|
||||
populateSimpleTrie(simpleTrie, host.split('').reverse());
|
||||
|
||||
function ifProxyBySimpleTrie(host, simpleTrie) {
|
||||
var letters = host.split('').reverse();
|
||||
while(letters.length) {
|
||||
var letter = letters.shift();
|
||||
var arr = simpleTrie[letter];
|
||||
var link = arr[0];
|
||||
|
||||
if (link.length > letters.length)
|
||||
return false;
|
||||
|
||||
for( var i=0; i < link.length; ++i )
|
||||
if ( letters[i] !== link.charAt(i) )
|
||||
return false;
|
||||
|
||||
letters = letters.slice(link.length);
|
||||
simpleTrie = arr[1];
|
||||
if (!simpleTrie)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return generatePac( ifProxyBySimpleTrie, 'host', simpleTrie );
|
||||
|
||||
}
|
3
pac-generator/src/blocked-hosts-binary.js
Executable file
3
pac-generator/src/blocked-hosts-binary.js
Executable file
|
@ -0,0 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => generatePac( require('./ifBinaryFound'), 'host', hosts );
|
12
pac-generator/src/blocked-hosts-hash.js
Executable file
12
pac-generator/src/blocked-hosts-hash.js
Executable file
|
@ -0,0 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
var hostsHash = {'': true};
|
||||
hosts.forEach( host => hostsHash[host] = true );
|
||||
function ifProxyByHash(host, hostsHash) {
|
||||
while(!hostsHash[host])
|
||||
host = (host+'.').replace(/^\w*\./g);
|
||||
return host.length !== 0;
|
||||
}
|
||||
return generatePac( ifProxyByHash, 'host', hostsHash )
|
||||
};
|
27
pac-generator/src/blocked-hosts-plain-switch.js
Executable file
27
pac-generator/src/blocked-hosts-plain-switch.js
Executable file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
function ifProxyByPlainSwitch(host) {
|
||||
|
||||
function ifBlocked(host) {
|
||||
switch( host ) {
|
||||
//CASES
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var doms = host.split('.');
|
||||
|
||||
for( var endi = doms.length-1; endi >= 0; --endi )
|
||||
if (ifBlocked( doms.slice( endi ).join('.') ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var cases = hosts.map( host => 'case "'+host+'":' ).join('\n') +'\nreturn true;';
|
||||
var ifProxyString = ifProxyByPlainSwitch.toString().replace('//CASES', cases);
|
||||
|
||||
return generatePac( ifProxyString, 'host' );
|
||||
|
||||
}
|
25
pac-generator/src/blocked-hosts-reversed-binary.js
Executable file
25
pac-generator/src/blocked-hosts-reversed-binary.js
Executable file
|
@ -0,0 +1,25 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
var reverse = str => str.split('').reverse().join('');
|
||||
var reversedHosts = hosts.map( reverse ).sort();
|
||||
|
||||
function ifReversedBinaryFound(host, sortedArray) {
|
||||
target = host.split('').reverse().join('');
|
||||
var istart = 0;
|
||||
var iend = sortedArray.length - 1;
|
||||
|
||||
while (istart < iend) {
|
||||
var imid = istart + Math.floor( (iend - istart)*0.5 );
|
||||
if (target > sortedArray[imid])
|
||||
istart = imid + 1;
|
||||
else
|
||||
iend = imid;
|
||||
}
|
||||
return dnsDomainIs( host, sortedArray[iend].split('').reverse().join('') );
|
||||
}
|
||||
|
||||
return generatePac( ifReversedBinaryFound, 'host', reversedHosts );
|
||||
|
||||
}
|
79
pac-generator/src/blocked-hosts-switch.js
Executable file
79
pac-generator/src/blocked-hosts-switch.js
Executable file
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
function populateTrie(trie, doms) {
|
||||
|
||||
var dom = doms.pop();
|
||||
if (!doms.length || doms.length === 1 && doms[0] === 'www') {
|
||||
trie[''] = trie[''] || [];
|
||||
trie[''].push( dom )
|
||||
return trie;
|
||||
}
|
||||
|
||||
if (trie[''] && trie[''].indexOf(dom) !== -1) // Subdomain of a blocked domain.
|
||||
return trie;
|
||||
|
||||
trie[dom] = trie[dom] || {};
|
||||
|
||||
populateTrie( trie[dom], doms );
|
||||
return trie;
|
||||
}
|
||||
|
||||
var trie = {};
|
||||
for(var host of hosts) {
|
||||
var doms = host.split('.');
|
||||
populateTrie(trie, doms);
|
||||
}
|
||||
|
||||
function trieToSwitch(trie, indent) {
|
||||
var _indent = indent || '';
|
||||
var indent = _indent + ' ';
|
||||
var keys = Object.keys(trie).sort();
|
||||
|
||||
if (!trie[''] && keys.length === 1) {
|
||||
var key = keys[0];
|
||||
return _indent + 'if (doms.pop() === "'+key+'")\n'+ trieToSwitch(trie[key], indent);
|
||||
}
|
||||
|
||||
var cases = '';
|
||||
if (trie['']) {
|
||||
var values = trie[''].sort();
|
||||
|
||||
if (values.length === 1 && keys.length === 1)
|
||||
return _indent + 'return doms.pop() === "'+values[0]+'";\n';
|
||||
|
||||
cases =
|
||||
values.filter( v => v ).map( val => indent +'case "'+val+'":\n' ).join('') + indent +' return true;\n';
|
||||
|
||||
delete trie[''];
|
||||
keys = Object.keys(trie).sort();
|
||||
}
|
||||
|
||||
cases += keys.filter( k => k ).map(
|
||||
key => {
|
||||
var tmp = trieToSwitch( trie[key], indent+' ');
|
||||
if (!/^\s*return/.test(tmp))
|
||||
tmp += indent+' break;\n';
|
||||
|
||||
return indent +'case "'+key+'":\n' +tmp;
|
||||
}
|
||||
).join('');
|
||||
|
||||
return ''
|
||||
+ _indent +'switch( doms.pop() ) {\n'
|
||||
+ cases
|
||||
+ _indent +'}\n';
|
||||
}
|
||||
|
||||
function ifProxyByTrie(host) {
|
||||
var doms = host.split('.');
|
||||
//SWITCH
|
||||
return false;
|
||||
}
|
||||
|
||||
var ifProxyByTrieStr = ifProxyByTrie.toString().replace('//SWITCH', trieToSwitch(trie, ' '));
|
||||
|
||||
return generatePac( ifProxyByTrieStr, 'host' );
|
||||
|
||||
}
|
3
pac-generator/src/blocked-ips-binary.js
Executable file
3
pac-generator/src/blocked-ips-binary.js
Executable file
|
@ -0,0 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => generatePac( require('./ifBinaryFound'), 'dnsResolve(host)', ips );
|
20
pac-generator/src/blocked-ips-indexOf.js
Executable file
20
pac-generator/src/blocked-ips-indexOf.js
Executable file
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
function ifProxyByIp(host, blockedIpsArray) {
|
||||
|
||||
// Internet Explorer
|
||||
if (!Array.prototype.indexOf)
|
||||
Array.prototype.indexOf = function(obj, start) {
|
||||
for (var i = (start || 0), j = this.length; i < j; i++)
|
||||
if (this[i] === obj) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return blockedIpsArray.indexOf( dnsResolve(host) ) !== -1
|
||||
}
|
||||
|
||||
return generatePac( ifProxyByIp, 'host', ips );
|
||||
|
||||
}
|
17
pac-generator/src/blocked-ips-switch.js
Executable file
17
pac-generator/src/blocked-ips-switch.js
Executable file
|
@ -0,0 +1,17 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = (hosts, ips, generator, generatePac) => {
|
||||
|
||||
function ifProxyBySwitch(host) {
|
||||
switch( dnsResolve(host) ) {
|
||||
//CASES
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var cases = ips.map( ip => 'case "'+ip+'":' ).join('\n') +'\nreturn true;';
|
||||
var ifProxySwitchStr = ifProxyBySwitch.toString().replace('//CASES', cases);
|
||||
|
||||
return generatePac( ifProxySwitchStr, 'host' );
|
||||
|
||||
}
|
18
pac-generator/src/ifBinaryFound.js
Executable file
18
pac-generator/src/ifBinaryFound.js
Executable file
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
function ifBinaryFound(target, sortedArray) {
|
||||
var istart = 0;
|
||||
var iend = sortedArray.length - 1;
|
||||
|
||||
while (istart < iend) {
|
||||
var imid = istart + Math.floor( (iend - istart)*0.5 );
|
||||
if (target > sortedArray[imid])
|
||||
istart = imid + 1;
|
||||
else
|
||||
iend = imid;
|
||||
}
|
||||
|
||||
return target === sortedArray[iend];
|
||||
}
|
||||
|
||||
module.exports = ifBinaryFound;
|
10
package.json
10
package.json
|
@ -4,13 +4,11 @@
|
|||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"generate": "node generate-PACs.js",
|
||||
"generate": "cd pac-generator && npm start",
|
||||
"prestart": "npm run generate",
|
||||
"preserve": "npm run kill",
|
||||
"serve": "START /B http-server generated-PACs",
|
||||
"bench": "cd Benchmark && dnx run ../generated-PACs",
|
||||
"start": "npm run bench",
|
||||
"kill": "taskkill /F /IM node.exe"
|
||||
"start": "npm run bench",
|
||||
"bench": "cd Benchmark && dnx run ../pac-generator/generated-PACs",
|
||||
"test": "rm -r pac-generator/generated-PACs"
|
||||
},
|
||||
"author": "ilyaigpetrov",
|
||||
"license": "ISC",
|
||||
|
|
Loading…
Reference in New Issue
Block a user