/*
翻墙回国 PAC 规则片段
*/
var proxy = "SOCKS5 127.0.0.1:1086; SOCKS 127.0.0.1:1086; DIRECT;";
var rules = [
"||dingtalk.com",
"||reddianjing.com",
"||jxedt.com",
"||truste.com",
"||wjx.cn",
"||mct.gov.cn",
"||360baoxian.net",
"||aliyun.com",
"||whhd.gov.cn",
"||moji001.com",
"||kanzhun.com",
"||aixifan.com",
"||canet.com.cn",
"||globalsign.com",
"||mapbar.com",
"||caict.ac.cn",
"||smm.cn",
"||ymzhaopin.com",
"||autonavi.com",
"||alibabapictures.com",
"||etao.com",
"||guahao.com",
"||51jingying.com",
"||wa.me",
"||jia.com",
"||hikunpeng.com",
"||dribbble.com",
"||qunarcdn.com",
"||motorsport-safety.org",
"||westartrack.com",
"||bestb2b.com",
"||shjbzx.cn",
"||58.com",
"||acfun.cn",
"||cnmstl.net",
"||zbj.com",
"||offcn.com",
"||tencentmusic.com",
"||beian.gov.cn",
"||boosj.com",
"||eztravel.com.tw",
"||zzit.com.cn",
"||sogou.com",
"||alios.cn",
"||zol-img.com.cn",
"||fliggy.com",
"||360kan.com",
"||yunos.com",
"||firefox.com.cn",
"||itrust.org.cn",
"||zx123.cn",
"||shibangchina.com",
"||antfin.com",
"||yuwenmi.com",
"||360.com",
"||glass.com.cn",
"||bjjubao.org",
"||11467.com",
"||piyao.org.cn",
"||qqtn.com",
"||59wz.com",
"||wingontravel.com",
"||zgjsks.com",
"||xinmin.cn",
"||qlrc.com",
"||migudm.cn",
"||tmall.com",
"||knet.cn",
"||mojicb.com",
"||tbcdn.com",
"||wps.cn",
"||fang.com",
"||xcc.cn",
"||58pic.com",
"||yellowurl.cn",
"||tuniu.com",
"||gcs-web.com",
"||58cdn.com.cn",
"||5i5j.com",
"||chaopx.com",
"||eoffcn.com",
"||secrss.com",
"||64365.com",
"||yiche.com",
"||douyucdn.cn",
"||iqiyipic.com",
"||xueqiu.com",
"||eastday.com",
"||cloudfront.net",
"||218.242.124.22",
"||699pic.com",
"||youdaoads.com",
"||downza.cn",
"||cnipa.gov.cn",
"||chinapp.com",
"||cookiebot.com",
"||bjjubao.org.cn",
"||hotjar.com",
"||wangxiao.cn",
"||antgroup.com",
"||sh.gov.cn",
"||wggames.cn",
"||daojia.com",
"||xunbao178.com",
"||goodjobs.cn",
"||kztpms.com",
"||ctrip.com",
"||cifnews.com",
"||souhu.com",
"||dongqiudi.com",
"||doubanio.com",
"||gsxt.gov.cn",
"||ebs.org.cn",
"||yizhentv.com",
"||netbian.com",
"||liepin.com",
"||processon.com",
"||xinhuanet.com",
"||migu.cn",
"||360.cn",
"||xunlei.com",
"||sz.gov.cn",
"||snet.tv",
"||97973.com",
"||wenmi.com",
"||dongao.com",
"||maimai.cn",
"||gaoding.com",
"||miguvideo.com",
"||xuexila.com",
"||qlogo.cn",
"||jobui.com",
"||58che.com",
"||kuaishou.cn",
"||jst.go.jp",
"||mmstat.com",
"||xibojiaoyu.com",
"||127.net",
"||znds.com",
"||602.com",
"||sohu.com.cn",
"||pconline.com.cn",
"||kaola.com",
"||bdstatic.com",
"||meituan.com",
"||12377.cn",
"||findlaw.cn",
"||lmlq.com",
"||braintreepayments.com",
"||aligames.com",
"||114ic.com",
"||taobao.com",
"||wjx.top",
"||jdcorporateblog.com",
"||qunar.com",
"||jianzhi8.com",
"||360buyimg.com",
"||99114.com",
"||imedao.com",
"||szfw.org",
"||weibo.cn",
"||mesign.com",
"||ele.me",
"||xcar.com.cn",
"||pmph.com",
"||mw.company",
"||radio366.com",
"||iqiyi.com",
"||sinajs.cn",
"||shdf.gov.cn",
"||izihun.com",
"||onethingcloud.com",
"||xiami.com",
"||mps.gov.cn",
"||cecdc.com",
"||anjuke.com",
"||fkguolu.com",
"||anquanke.com",
"||doi.org",
"||woshipm.com",
"||alipay.cn",
"||mfa.gov.cn",
"||zzfangkuai.com",
"||cmvideo.cn",
"||hiyayuyin.com",
"||kuwo.cn",
"||818ps.com",
"||huaweicloud.com",
"||aipai.com",
"||trustutn.org",
"||qingxuetang.com",
"||tujia.com",
"||weishi.com",
"||acgvideo.com",
"||manmankan.com",
"||ccwork.com.cn",
"||zmxy.com.cn",
"||dangbei.com",
"||xycloud.com",
"||douyu.com",
"||mi.com",
"||kongfz.com",
"||wechat.com",
"||momo.com",
"||umeng.com",
"||renren.com",
"||douban.com",
"||chinahr.com",
"||flipsnack.com",
"||zhihu.com",
"||027art.com",
"||sxdn.com.cn",
"||job5156.com",
"||9ku.com",
"||hunliji.com",
"||suning.com",
"||hunantv.com",
"||feishu.cn",
"||tencent.com",
"||lizhi.fm",
"||ifcert.cn",
"||jumei.com",
"||zhipin.com",
"||360.net",
"||bcebos.com",
"||wanmei.com",
"||alimama.com",
"||itc.cn",
"||kuaishou.com",
"||tmall.hk",
"||zgsydw.com",
"||verisign.com",
"||saic.gov.cn",
"||huawei.com",
"||kaolacdn.com",
"||aliexpress.com",
"||1637.com",
"||viptijian.com",
"||trip.com",
"||danjuanfunds.com",
"||chinairn.com",
"||url.cn",
"||leju.com",
"||jiaobu365.com",
"||geetest.com",
"||163yun.com",
"||duwenzhang.com",
"||baobao88.com",
"||bmlink.com",
"||ctripins.com",
"||1010jiajiao.com",
"||tianqi.com",
"||shipin520.com",
"||360totalsecurity.com",
"||360jie.com.cn",
"||qihucdn.com",
"||dpurl.cn",
"||v-56.com",
"||trustexporter.com",
"||cntrades.com",
"||picmoon.com",
"||ximalaya.com",
"||ibaotu.com",
"||klaviyo.com",
"||figma.com",
"||51mdd.com",
"||baidupcs.com",
"||alitrip.com",
"||alibabagroup.com",
"||sina.com",
"||uc.cn",
"||ca.gov",
"||baixing.com",
"||alibaba.com",
"||czvv.com",
"||cnzz.com",
"||job592.com",
"||alipay.com",
"||loupan.com",
"||autohome.com.cn",
"||fjzol.com",
"||qingting.fm",
"||tieyou.com",
"||wechat.design",
"||alicdn.com",
"||qpic.cn",
"||hitv.com",
"||360safe.com",
"||sz315.org",
"||ucweb.com",
"||sina.cn",
"||ynit580.com",
"||com",
"||mogucdn.com",
"||huibo.com",
"||aliwx.com.cn",
"||jianshu.com",
"||huazhen2008.com",
"||zhenghaoyou.com",
"||szcredit.org.cn",
"||soso.com",
"||to8to.com",
"||zhuanzhuan.com",
"||xiaomi.com",
"||1ppt.com",
"||zjfda.gov.cn",
"||mogujie.com",
"||cyberpolice.cn",
"||atsec.cn",
"||hotjob.cn",
"||jiemeng8.com",
"||eqxiu.com",
"||mike-x.com",
"||51auto.com",
"||qianxin.com",
"||sandai.net",
"||weibo.com",
"||pinduoduo.com",
"||kugou.com",
"||yystatic.com",
"||qqyou.com",
"||xiami.net",
"||bytedance.com",
"||crup.cn",
"||toursforfun.com",
"||gaoxiaojob.com",
"||maoyan.com",
"||t.cn",
"||c-ctrip.com",
"||so.com",
"||miaopai.com",
"||yunaq.com",
"||toutiao.com",
"||fangcloud.com",
"||zx110.org",
"||ccm.gov.cn",
"||gongchang.com",
"||people-health.cn",
"||netentsec.com",
"||126.com",
"||xnimg.cn",
"||taodocs.com",
"||xmcdn.com",
"||creditchina.gov.cn",
"||damai.cn",
"||onething.net",
"||ithome.com",
"||hdslb.com",
"||miit.gov.cn",
"||sinaimg.cn",
"||jd.com",
"||xuexi.la",
"||hrflag.com",
"||bilibili.com",
"||mozilla.org",
"||51sole.com",
"||thunderurl.com",
"||gzjd.gov.cn",
"||youbian.com",
"||cnki.net",
"||eduei.com",
"||weixin.com",
"||qtfm.cn",
"||xizhi-ec.com",
"||heiyan.com",
"||jnupress.com",
"||youku.com",
"||tudou.com",
"||tiktokcdn.com",
"||66law.cn",
"||zj.gov.cn",
"||ooopic.com",
"||588ku.com",
"||qq.com",
"||ykimg.com",
"||photophoto.cn",
"||china.cn",
"||4399.com",
"||moji.com",
"||qixin.com",
"||zol.com",
"||meituan.net",
"||vip.com",
"||qiantucdn.com",
"||zol.com.cn",
"||cnhubei.com",
"||acfun.com",
"||gtimg.cn",
"||xzgoogle.com",
"||soku.com",
"||youku.tv",
"||alibabacloud.com",
"||qianlima.com",
"||beijing.gov.cn",
"||4.cn",
"||yiqifa.com",
"||gdjubao.cn",
"||ganji.com",
"||tooopen.com",
"||csdn.net",
"||liuxue86.com",
"||5068.com",
"||51yes.com",
"||360kuai.com",
"||tmtpost.com",
"||airmb.com",
"||affirm.com",
"||56.com",
"||kuaijianji.com",
"||jqw.com",
"||yue365.com",
"||youdao.com",
"||xiumi.us",
"||douban.fm",
"||netease.com",
"||westarchain.com",
"||ximalayaos.com",
"||mybank.cn",
"||roodoo.net",
"||ifeng.com",
"||njupco.com",
"||gcimg.net",
"||12306.cn",
"||xunbaozhifu.com",
"||hhtravel.com",
"||lvmama.com",
"||xiaoka.tv",
"||yimeishe.com",
"||amap.com",
"||sina.com.cn",
"||yy.com",
"||mogu.com",
"||xizhi.com",
"||examw.com",
"||sse.com.cn",
"||1688.com",
"||houxue.com",
"||zhimg.com",
"||huatu.com",
"||qianzhan.com",
"||tianyancha.com",
"||fun.tv",
"||icourse163.org",
"||mogu-inc.com",
"||koowo.com",
"||hiascend.com",
"||qiche.com",
"||zjjubao.com",
"||chinasspp.com",
"||sohu.com",
"||115.com",
"||9game.cn",
"||51jiaoxi.com",
"||wenming.cn",
"||dianping.com",
"||mgtv.com",
"||faloo.com",
"||tanmizhi.com",
"||qy.net",
"||lagou.com",
"||butian.net",
"||nicaifu.com",
"||baidu.com",
"||12315.cn",
"||zhibo8.cc",
"||houzi8.com",
"||51job.com",
"||yinyuetai.com",
"||bitauto.com",
"||gucheng.com",
"||zhiding.com.cn",
"||126.net",
"||mokahr.com",
"||legendsec.com",
"||phb123.com",
"||kanman.com",
"||wandoujia.com",
"||fbook.net",
"||lolshipin.com",
"||alihealth.cn",
"||eduego.com",
"||lawtime.cn",
"||huangye88.com",
"||qianqian.com",
"||miibeian.gov.cn",
"||wp.me",
"||gaosan.com",
"||youhaosuda.com",
"||163.com",
"||herostart.com",
"||tiaojie.net.cn",
"||dianzhangzhipin.com",
"||yhd.com",
"||mikecrm.com",
"||hichina.com",
"||vipshop.com",
];
/*
* This file is part of Adblock Plus ,
* Copyright (C) 2006-2014 Eyeo GmbH
*
* Adblock Plus is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* Adblock Plus is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Adblock Plus. If not, see .
*/
function createDict()
{
var result = {};
result.__proto__ = null;
return result;
}
function getOwnPropertyDescriptor(obj, key)
{
if (obj.hasOwnProperty(key))
{
return obj[key];
}
return null;
}
function extend(subclass, superclass, definition)
{
if (Object.__proto__)
{
definition.__proto__ = superclass.prototype;
subclass.prototype = definition;
}
else
{
var tmpclass = function(){}, ret;
tmpclass.prototype = superclass.prototype;
subclass.prototype = new tmpclass();
subclass.prototype.constructor = superclass;
for (var i in definition)
{
if (definition.hasOwnProperty(i))
{
subclass.prototype[i] = definition[i];
}
}
}
}
function Filter(text)
{
this.text = text;
this.subscriptions = [];
}
Filter.prototype = {
text: null,
subscriptions: null,
toString: function()
{
return this.text;
}
};
Filter.knownFilters = createDict();
Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(\@)?(?:([\w\-]+|\*)((?:\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/;
Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/;
Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/;
Filter.fromText = function(text)
{
if (text in Filter.knownFilters)
{
return Filter.knownFilters[text];
}
var ret;
if (text[0] == "!")
{
ret = new CommentFilter(text);
}
else
{
ret = RegExpFilter.fromText(text);
}
Filter.knownFilters[ret.text] = ret;
return ret;
};
function InvalidFilter(text, reason)
{
Filter.call(this, text);
this.reason = reason;
}
extend(InvalidFilter, Filter, {
reason: null
});
function CommentFilter(text)
{
Filter.call(this, text);
}
extend(CommentFilter, Filter, {
});
function ActiveFilter(text, domains)
{
Filter.call(this, text);
this.domainSource = domains;
}
extend(ActiveFilter, Filter, {
domainSource: null,
domainSeparator: null,
ignoreTrailingDot: true,
domainSourceIsUpperCase: false,
getDomains: function()
{
var prop = getOwnPropertyDescriptor(this, "domains");
if (prop)
{
return prop;
}
var domains = null;
if (this.domainSource)
{
var source = this.domainSource;
if (!this.domainSourceIsUpperCase)
{
source = source.toUpperCase();
}
var list = source.split(this.domainSeparator);
if (list.length == 1 && list[0][0] != "~")
{
domains = createDict();
domains[""] = false;
if (this.ignoreTrailingDot)
{
list[0] = list[0].replace(/\.+$/, "");
}
domains[list[0]] = true;
}
else
{
var hasIncludes = false;
for (var i = 0; i < list.length; i++)
{
var domain = list[i];
if (this.ignoreTrailingDot)
{
domain = domain.replace(/\.+$/, "");
}
if (domain == "")
{
continue;
}
var include;
if (domain[0] == "~")
{
include = false;
domain = domain.substr(1);
}
else
{
include = true;
hasIncludes = true;
}
if (!domains)
{
domains = createDict();
}
domains[domain] = include;
}
domains[""] = !hasIncludes;
}
this.domainSource = null;
}
return this.domains;
},
sitekeys: null,
isActiveOnDomain: function(docDomain, sitekey)
{
if (this.getSitekeys() && (!sitekey || this.getSitekeys().indexOf(sitekey.toUpperCase()) < 0))
{
return false;
}
if (!this.getDomains())
{
return true;
}
if (!docDomain)
{
return this.getDomains()[""];
}
if (this.ignoreTrailingDot)
{
docDomain = docDomain.replace(/\.+$/, "");
}
docDomain = docDomain.toUpperCase();
while (true)
{
if (docDomain in this.getDomains())
{
return this.domains[docDomain];
}
var nextDot = docDomain.indexOf(".");
if (nextDot < 0)
{
break;
}
docDomain = docDomain.substr(nextDot + 1);
}
return this.domains[""];
},
isActiveOnlyOnDomain: function(docDomain)
{
if (!docDomain || !this.getDomains() || this.getDomains()[""])
{
return false;
}
if (this.ignoreTrailingDot)
{
docDomain = docDomain.replace(/\.+$/, "");
}
docDomain = docDomain.toUpperCase();
for (var domain in this.getDomains())
{
if (this.domains[domain] && domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))
{
return false;
}
}
return true;
}
});
function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)
{
ActiveFilter.call(this, text, domains, sitekeys);
if (contentType != null)
{
this.contentType = contentType;
}
if (matchCase)
{
this.matchCase = matchCase;
}
if (thirdParty != null)
{
this.thirdParty = thirdParty;
}
if (sitekeys != null)
{
this.sitekeySource = sitekeys;
}
if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/")
{
var regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");
this.regexp = regexp;
}
else
{
this.regexpSource = regexpSource;
}
}
extend(RegExpFilter, ActiveFilter, {
domainSourceIsUpperCase: true,
length: 1,
domainSeparator: "|",
regexpSource: null,
getRegexp: function()
{
var prop = getOwnPropertyDescriptor(this, "regexp");
if (prop)
{
return prop;
}
var source = this.regexpSource.replace(/\*+/g, "*").replace(/\^\|$/, "^").replace(/\W/g, "\\$&").replace(/\\\*/g, ".*").replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x7F]|$)").replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?").replace(/^\\\|/, "^").replace(/\\\|$/, "$").replace(/^(\.\*)/, "").replace(/(\.\*)$/, "");
var regexp = new RegExp(source, this.matchCase ? "" : "i");
this.regexp = regexp;
return regexp;
},
contentType: 2147483647,
matchCase: false,
thirdParty: null,
sitekeySource: null,
getSitekeys: function()
{
var prop = getOwnPropertyDescriptor(this, "sitekeys");
if (prop)
{
return prop;
}
var sitekeys = null;
if (this.sitekeySource)
{
sitekeys = this.sitekeySource.split("|");
this.sitekeySource = null;
}
this.sitekeys = sitekeys;
return this.sitekeys;
},
matches: function(location, contentType, docDomain, thirdParty, sitekey)
{
if (this.getRegexp().test(location) && this.isActiveOnDomain(docDomain, sitekey))
{
return true;
}
return false;
}
});
RegExpFilter.prototype["0"] = "#this";
RegExpFilter.fromText = function(text)
{
var blocking = true;
var origText = text;
if (text.indexOf("@@") == 0)
{
blocking = false;
text = text.substr(2);
}
var contentType = null;
var matchCase = null;
var domains = null;
var sitekeys = null;
var thirdParty = null;
var collapse = null;
var options;
var match = text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null;
if (match)
{
options = match[1].toUpperCase().split(",");
text = match.input.substr(0, match.index);
for (var _loopIndex6 = 0; _loopIndex6 < options.length; ++_loopIndex6)
{
var option = options[_loopIndex6];
var value = null;
var separatorIndex = option.indexOf("=");
if (separatorIndex >= 0)
{
value = option.substr(separatorIndex + 1);
option = option.substr(0, separatorIndex);
}
option = option.replace(/-/, "_");
if (option in RegExpFilter.typeMap)
{
if (contentType == null)
{
contentType = 0;
}
contentType |= RegExpFilter.typeMap[option];
}
else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap)
{
if (contentType == null)
{
contentType = RegExpFilter.prototype.contentType;
}
contentType &= ~RegExpFilter.typeMap[option.substr(1)];
}
else if (option == "MATCH_CASE")
{
matchCase = true;
}
else if (option == "~MATCH_CASE")
{
matchCase = false;
}
else if (option == "DOMAIN" && typeof value != "undefined")
{
domains = value;
}
else if (option == "THIRD_PARTY")
{
thirdParty = true;
}
else if (option == "~THIRD_PARTY")
{
thirdParty = false;
}
else if (option == "COLLAPSE")
{
collapse = true;
}
else if (option == "~COLLAPSE")
{
collapse = false;
}
else if (option == "SITEKEY" && typeof value != "undefined")
{
sitekeys = value;
}
else
{
return new InvalidFilter(origText, "Unknown option " + option.toLowerCase());
}
}
}
if (!blocking && (contentType == null || contentType & RegExpFilter.typeMap.DOCUMENT) && (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text))
{
if (contentType == null)
{
contentType = RegExpFilter.prototype.contentType;
}
contentType &= ~RegExpFilter.typeMap.DOCUMENT;
}
try
{
if (blocking)
{
return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse);
}
else
{
return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys);
}
}
catch (e)
{
return new InvalidFilter(origText, e);
}
};
RegExpFilter.typeMap = {
OTHER: 1,
SCRIPT: 2,
IMAGE: 4,
STYLESHEET: 8,
OBJECT: 16,
SUBDOCUMENT: 32,
DOCUMENT: 64,
XBL: 1,
PING: 1,
XMLHTTPREQUEST: 2048,
OBJECT_SUBREQUEST: 4096,
DTD: 1,
MEDIA: 16384,
FONT: 32768,
BACKGROUND: 4,
POPUP: 268435456,
ELEMHIDE: 1073741824
};
RegExpFilter.prototype.contentType &= ~ (RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP);
function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse)
{
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
this.collapse = collapse;
}
extend(BlockingFilter, RegExpFilter, {
collapse: null
});
function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)
{
RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);
}
extend(WhitelistFilter, RegExpFilter, {
});
function Matcher()
{
this.clear();
}
Matcher.prototype = {
filterByKeyword: null,
keywordByFilter: null,
clear: function()
{
this.filterByKeyword = createDict();
this.keywordByFilter = createDict();
},
add: function(filter)
{
if (filter.text in this.keywordByFilter)
{
return;
}
var keyword = this.findKeyword(filter);
var oldEntry = this.filterByKeyword[keyword];
if (typeof oldEntry == "undefined")
{
this.filterByKeyword[keyword] = filter;
}
else if (oldEntry.length == 1)
{
this.filterByKeyword[keyword] = [oldEntry, filter];
}
else
{
oldEntry.push(filter);
}
this.keywordByFilter[filter.text] = keyword;
},
remove: function(filter)
{
if (!(filter.text in this.keywordByFilter))
{
return;
}
var keyword = this.keywordByFilter[filter.text];
var list = this.filterByKeyword[keyword];
if (list.length <= 1)
{
delete this.filterByKeyword[keyword];
}
else
{
var index = list.indexOf(filter);
if (index >= 0)
{
list.splice(index, 1);
if (list.length == 1)
{
this.filterByKeyword[keyword] = list[0];
}
}
}
delete this.keywordByFilter[filter.text];
},
findKeyword: function(filter)
{
var result = "";
var text = filter.text;
if (Filter.regexpRegExp.test(text))
{
return result;
}
var match = Filter.optionsRegExp.exec(text);
if (match)
{
text = match.input.substr(0, match.index);
}
if (text.substr(0, 2) == "@@")
{
text = text.substr(2);
}
var candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g);
if (!candidates)
{
return result;
}
var hash = this.filterByKeyword;
var resultCount = 16777215;
var resultLength = 0;
for (var i = 0, l = candidates.length; i < l; i++)
{
var candidate = candidates[i].substr(1);
var count = candidate in hash ? hash[candidate].length : 0;
if (count < resultCount || count == resultCount && candidate.length > resultLength)
{
result = candidate;
resultCount = count;
resultLength = candidate.length;
}
}
return result;
},
hasFilter: function(filter)
{
return filter.text in this.keywordByFilter;
},
getKeywordForFilter: function(filter)
{
if (filter.text in this.keywordByFilter)
{
return this.keywordByFilter[filter.text];
}
else
{
return null;
}
},
_checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty, sitekey)
{
var list = this.filterByKeyword[keyword];
for (var i = 0; i < list.length; i++)
{
var filter = list[i];
if (filter == "#this")
{
filter = list;
}
if (filter.matches(location, contentType, docDomain, thirdParty, sitekey))
{
return filter;
}
}
return null;
},
matchesAny: function(location, contentType, docDomain, thirdParty, sitekey)
{
var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
if (candidates === null)
{
candidates = [];
}
candidates.push("");
for (var i = 0, l = candidates.length; i < l; i++)
{
var substr = candidates[i];
if (substr in this.filterByKeyword)
{
var result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
if (result)
{
return result;
}
}
}
return null;
}
};
function CombinedMatcher()
{
this.blacklist = new Matcher();
this.whitelist = new Matcher();
this.resultCache = createDict();
}
CombinedMatcher.maxCacheEntries = 1000;
CombinedMatcher.prototype = {
blacklist: null,
whitelist: null,
resultCache: null,
cacheEntries: 0,
clear: function()
{
this.blacklist.clear();
this.whitelist.clear();
this.resultCache = createDict();
this.cacheEntries = 0;
},
add: function(filter)
{
if (filter instanceof WhitelistFilter)
{
this.whitelist.add(filter);
}
else
{
this.blacklist.add(filter);
}
if (this.cacheEntries > 0)
{
this.resultCache = createDict();
this.cacheEntries = 0;
}
},
remove: function(filter)
{
if (filter instanceof WhitelistFilter)
{
this.whitelist.remove(filter);
}
else
{
this.blacklist.remove(filter);
}
if (this.cacheEntries > 0)
{
this.resultCache = createDict();
this.cacheEntries = 0;
}
},
findKeyword: function(filter)
{
if (filter instanceof WhitelistFilter)
{
return this.whitelist.findKeyword(filter);
}
else
{
return this.blacklist.findKeyword(filter);
}
},
hasFilter: function(filter)
{
if (filter instanceof WhitelistFilter)
{
return this.whitelist.hasFilter(filter);
}
else
{
return this.blacklist.hasFilter(filter);
}
},
getKeywordForFilter: function(filter)
{
if (filter instanceof WhitelistFilter)
{
return this.whitelist.getKeywordForFilter(filter);
}
else
{
return this.blacklist.getKeywordForFilter(filter);
}
},
isSlowFilter: function(filter)
{
var matcher = filter instanceof WhitelistFilter ? this.whitelist : this.blacklist;
if (matcher.hasFilter(filter))
{
return !matcher.getKeywordForFilter(filter);
}
else
{
return !matcher.findKeyword(filter);
}
},
matchesAnyInternal: function(location, contentType, docDomain, thirdParty, sitekey)
{
var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
if (candidates === null)
{
candidates = [];
}
candidates.push("");
var blacklistHit = null;
for (var i = 0, l = candidates.length; i < l; i++)
{
var substr = candidates[i];
if (substr in this.whitelist.filterByKeyword)
{
var result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
if (result)
{
return result;
}
}
if (substr in this.blacklist.filterByKeyword && blacklistHit === null)
{
blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);
}
}
return blacklistHit;
},
matchesAny: function(location, docDomain)
{
var key = location + " " + docDomain + " ";
if (key in this.resultCache)
{
return this.resultCache[key];
}
var result = this.matchesAnyInternal(location, 0, docDomain, null, null);
if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)
{
this.resultCache = createDict();
this.cacheEntries = 0;
}
this.resultCache[key] = result;
this.cacheEntries++;
return result;
}
};
var defaultMatcher = new CombinedMatcher();
var direct = 'DIRECT;';
for (var i = 0; i < rules.length; i++) {
defaultMatcher.add(Filter.fromText(rules[i]));
}
function FindProxyForURL(url, host) {
if (defaultMatcher.matchesAny(url, host) instanceof BlockingFilter) {
return proxy;
}
return direct;
}