# from PixivSearch.model.config import rule import base64 import requests from PixivSearch.model.config import rule def create(): response = requests.get('https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt') if response.status_code == 200: gfwlistText = (str)(base64.b64decode(response.content).decode('utf-8')) gfwlist=gfwlistText.split('\n')[1:] pacScript= 'var proxy = "PROXY 127.0.0.1:1080;";\n' \ 'var rules = [\n' for line in gfwlist: if len(line)>0 and not line.startswith('!'): # print(line) pacScript+='"'+line+'",\n' for line in rule.objects.all(): pacScript+='"'+line.regex+'",\n' # print(pacScript[:-2]) pacScript=pacScript[:-2]+'\n];\n' \ 'function createDict()\n' \ '{\n' \ ' var result = {};\n' \ ' result.__proto__ = null;\n' \ ' return result;\n' \ '}\n' \ '\n' \ 'function getOwnPropertyDescriptor(obj, key)\n' \ '{\n' \ ' if (obj.hasOwnProperty(key))\n' \ ' {\n' \ ' return obj[key];\n' \ ' }\n' \ ' return null;\n' \ '}\n' \ '\n' \ 'function extend(subclass, superclass, definition)\n' \ '{\n' \ ' if (Object.__proto__)\n' \ ' {\n' \ ' definition.__proto__ = superclass.prototype;\n' \ ' subclass.prototype = definition;\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' var tmpclass = function(){}, ret;\n' \ ' tmpclass.prototype = superclass.prototype;\n' \ ' subclass.prototype = new tmpclass();\n' \ ' subclass.prototype.constructor = superclass;\n' \ ' for (var i in definition)\n' \ ' {\n' \ ' if (definition.hasOwnProperty(i))\n' \ ' {\n' \ ' subclass.prototype[i] = definition[i];\n' \ ' }\n' \ ' }\n' \ ' }\n' \ '}\n' \ '\n' \ 'function Filter(text)\n' \ '{\n' \ ' this.text = text;\n' \ ' this.subscriptions = [];\n' \ '}\n' \ 'Filter.prototype = {\n' \ ' text: null,\n' \ ' subscriptions: null,\n' \ ' toString: function()\n' \ ' {\n' \ ' return this.text;\n' \ ' }\n' \ '};\n' \ 'Filter.knownFilters = createDict();\n' \ 'Filter.elemhideRegExp = /^([^\/\*\|\@"!]*?)#(\@)?(?:([\w\-]+|\*)((?:\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\))*)|#([^{}]+))$/;\n' \ 'Filter.regexpRegExp = /^(@@)?\/.*\/(?:\$~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)?$/;\n' \ 'Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/;\n' \ 'Filter.fromText = function(text)\n' \ '{\n' \ ' if (text in Filter.knownFilters)\n' \ ' {\n' \ ' return Filter.knownFilters[text];\n' \ ' }\n' \ ' var ret;\n' \ ' if (text.charAt(0) == "!")\n' \ ' {\n' \ ' ret = new CommentFilter(text);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' ret = RegExpFilter.fromText(text);\n' \ ' }\n' \ ' Filter.knownFilters[ret.text] = ret;\n' \ ' return ret;\n' \ '};\n' \ '\n' \ 'function InvalidFilter(text, reason)\n' \ '{\n' \ ' Filter.call(this, text);\n' \ ' this.reason = reason;\n' \ '}\n' \ 'extend(InvalidFilter, Filter, {\n' \ ' reason: null\n' \ '});\n' \ '\n' \ 'function CommentFilter(text)\n' \ '{\n' \ ' Filter.call(this, text);\n' \ '}\n' \ 'extend(CommentFilter, Filter, {\n' \ '});\n' \ '\n' \ 'function ActiveFilter(text, domains)\n' \ '{\n' \ ' Filter.call(this, text);\n' \ ' this.domainSource = domains;\n' \ '}\n' \ 'extend(ActiveFilter, Filter, {\n' \ ' domainSource: null,\n' \ ' domainSeparator: null,\n' \ ' ignoreTrailingDot: true,\n' \ ' domainSourceIsUpperCase: false,\n' \ ' getDomains: function()\n' \ ' {\n' \ ' var prop = getOwnPropertyDescriptor(this, "domains");\n' \ ' if (prop)\n' \ ' {\n' \ ' return prop;\n' \ ' }\n' \ ' var domains = null;\n' \ ' if (this.domainSource)\n' \ ' {\n' \ ' var source = this.domainSource;\n' \ ' if (!this.domainSourceIsUpperCase)\n' \ ' {\n' \ ' source = source.toUpperCase();\n' \ ' }\n' \ ' var list = source.split(this.domainSeparator);\n' \ ' if (list.length == 1 && (list[0]).charAt(0) != "~")\n' \ ' {\n' \ ' domains = createDict();\n' \ ' domains[""] = false;\n' \ ' if (this.ignoreTrailingDot)\n' \ ' {\n' \ ' list[0] = list[0].replace(/\.+$/, "");\n' \ ' }\n' \ ' domains[list[0]] = true;\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' var hasIncludes = false;\n' \ ' for (var i = 0; i < list.length; i++)\n' \ ' {\n' \ ' var domain = list[i];\n' \ ' if (this.ignoreTrailingDot)\n' \ ' {\n' \ ' domain = domain.replace(/\.+$/, "");\n' \ ' }\n' \ ' if (domain == "")\n' \ ' {\n' \ ' continue;\n' \ ' }\n' \ ' var include;\n' \ ' if (domain.charAt(0) == "~")\n' \ ' {\n' \ ' include = false;\n' \ ' domain = domain.substr(1);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' include = true;\n' \ ' hasIncludes = true;\n' \ ' }\n' \ ' if (!domains)\n' \ ' {\n' \ ' domains = createDict();\n' \ ' }\n' \ ' domains[domain] = include;\n' \ ' }\n' \ ' domains[""] = !hasIncludes;\n' \ ' }\n' \ ' this.domainSource = null;\n' \ ' }\n' \ ' return this.domains;\n' \ ' },\n' \ ' sitekeys: null,\n' \ ' isActiveOnDomain: function(docDomain, sitekey)\n' \ ' {\n' \ ' if (this.getSitekeys() && (!sitekey || this.getSitekeys().indexOf(sitekey.toUpperCase()) < 0))\n' \ ' {\n' \ ' return false;\n' \ ' }\n' \ ' if (!this.getDomains())\n' \ ' {\n' \ ' return true;\n' \ ' }\n' \ ' if (!docDomain)\n' \ ' {\n' \ ' return this.getDomains()[""];\n' \ ' }\n' \ ' if (this.ignoreTrailingDot)\n' \ ' {\n' \ ' docDomain = docDomain.replace(/\.+$/, "");\n' \ ' }\n' \ ' docDomain = docDomain.toUpperCase();\n' \ ' while (true)\n' \ ' {\n' \ ' if (docDomain in this.getDomains())\n' \ ' {\n' \ ' return this.domains[docDomain];\n' \ ' }\n' \ ' var nextDot = docDomain.indexOf(".");\n' \ ' if (nextDot < 0)\n' \ ' {\n' \ ' break;\n' \ ' }\n' \ ' docDomain = docDomain.substr(nextDot + 1);\n' \ ' }\n' \ ' return this.domains[""];\n' \ ' },\n' \ ' isActiveOnlyOnDomain: function(docDomain)\n' \ ' {\n' \ ' if (!docDomain || !this.getDomains() || this.getDomains()[""])\n' \ ' {\n' \ ' return false;\n' \ ' }\n' \ ' if (this.ignoreTrailingDot)\n' \ ' {\n' \ ' docDomain = docDomain.replace(/\.+$/, "");\n' \ ' }\n' \ ' docDomain = docDomain.toUpperCase();\n' \ ' for (var domain in this.getDomains())\n' \ ' {\n' \ ' if (this.domains[domain] && domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))\n' \ ' {\n' \ ' return false;\n' \ ' }\n' \ ' }\n' \ ' return true;\n' \ ' }\n' \ '});\n' \ '\n' \ 'function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)\n' \ '{\n' \ ' ActiveFilter.call(this, text, domains, sitekeys);\n' \ ' if (contentType != null)\n' \ ' {\n' \ ' this.contentType = contentType;\n' \ ' }\n' \ ' if (matchCase)\n' \ ' {\n' \ ' this.matchCase = matchCase;\n' \ ' }\n' \ ' if (thirdParty != null)\n' \ ' {\n' \ ' this.thirdParty = thirdParty;\n' \ ' }\n' \ ' if (sitekeys != null)\n' \ ' {\n' \ ' this.sitekeySource = sitekeys;\n' \ ' }\n' \ ' if (regexpSource.length >= 2 && regexpSource.charAt(0) == "/" && regexpSource.charAt(regexpSource.length - 1) == "/")\n' \ ' {\n' \ ' var regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");\n' \ ' this.regexp = regexp;\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' this.regexpSource = regexpSource;\n' \ ' }\n' \ '}\n' \ 'extend(RegExpFilter, ActiveFilter, {\n' \ ' domainSourceIsUpperCase: true,\n' \ ' length: 1,\n' \ ' domainSeparator: "|",\n' \ ' regexpSource: null,\n' \ ' getRegexp: function()\n' \ ' {\n' \ ' var prop = getOwnPropertyDescriptor(this, "regexp");\n' \ ' if (prop)\n' \ ' {\n' \ ' return prop;\n' \ ' }\n' \ ' 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(/(\.\*)$/, "");\n' \ ' var regexp = new RegExp(source, this.matchCase ? "" : "i");\n' \ ' this.regexp = regexp;\n' \ ' return regexp;\n' \ ' },\n' \ ' contentType: 2147483647,\n' \ ' matchCase: false,\n' \ ' thirdParty: null,\n' \ ' sitekeySource: null,\n' \ ' getSitekeys: function()\n' \ ' {\n' \ ' var prop = getOwnPropertyDescriptor(this, "sitekeys");\n' \ ' if (prop)\n' \ ' {\n' \ ' return prop;\n' \ ' }\n' \ ' var sitekeys = null;\n' \ ' if (this.sitekeySource)\n' \ ' {\n' \ ' sitekeys = this.sitekeySource.split("|");\n' \ ' this.sitekeySource = null;\n' \ ' }\n' \ ' this.sitekeys = sitekeys;\n' \ ' return this.sitekeys;\n' \ ' },\n' \ ' matches: function(location, contentType, docDomain, thirdParty, sitekey)\n' \ ' {\n' \ ' if (this.getRegexp().test(location) && this.isActiveOnDomain(docDomain, sitekey))\n' \ ' {\n' \ ' return true;\n' \ ' }\n' \ ' return false;\n' \ ' }\n' \ '});\n' \ 'RegExpFilter.prototype["0"] = "#this";\n' \ 'RegExpFilter.fromText = function(text)\n' \ '{\n' \ ' var blocking = true;\n' \ ' var origText = text;\n' \ ' if (text.indexOf("@@") == 0)\n' \ ' {\n' \ ' blocking = false;\n' \ ' text = text.substr(2);\n' \ ' }\n' \ ' var contentType = null;\n' \ ' var matchCase = null;\n' \ ' var domains = null;\n' \ ' var sitekeys = null;\n' \ ' var thirdParty = null;\n' \ ' var collapse = null;\n' \ ' var options;\n' \ ' var match = text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null;\n' \ ' if (match)\n' \ ' {\n' \ ' options = match[1].toUpperCase().split(",");\n' \ ' text = match.input.substr(0, match.index);\n' \ ' for (var _loopIndex6 = 0; _loopIndex6 < options.length; ++_loopIndex6)\n' \ ' {\n' \ ' var option = options[_loopIndex6];\n' \ ' var value = null;\n' \ ' var separatorIndex = option.indexOf("=");\n' \ ' if (separatorIndex >= 0)\n' \ ' {\n' \ ' value = option.substr(separatorIndex + 1);\n' \ ' option = option.substr(0, separatorIndex);\n' \ ' }\n' \ ' option = option.replace(/-/, "_");\n' \ ' if (option in RegExpFilter.typeMap)\n' \ ' {\n' \ ' if (contentType == null)\n' \ ' {\n' \ ' contentType = 0;\n' \ ' }\n' \ ' contentType |= RegExpFilter.typeMap[option];\n' \ ' }\n' \ ' else if (option.charAt(0) == "~" && option.substr(1) in RegExpFilter.typeMap)\n' \ ' {\n' \ ' if (contentType == null)\n' \ ' {\n' \ ' contentType = RegExpFilter.prototype.contentType;\n' \ ' }\n' \ ' contentType &= ~RegExpFilter.typeMap[option.substr(1)];\n' \ ' }\n' \ ' else if (option == "MATCH_CASE")\n' \ ' {\n' \ ' matchCase = true;\n' \ ' }\n' \ ' else if (option == "~MATCH_CASE")\n' \ ' {\n' \ ' matchCase = false;\n' \ ' }\n' \ ' else if (option == "DOMAIN" && typeof value != "undefined")\n' \ ' {\n' \ ' domains = value;\n' \ ' }\n' \ ' else if (option == "THIRD_PARTY")\n' \ ' {\n' \ ' thirdParty = true;\n' \ ' }\n' \ ' else if (option == "~THIRD_PARTY")\n' \ ' {\n' \ ' thirdParty = false;\n' \ ' }\n' \ ' else if (option == "COLLAPSE")\n' \ ' {\n' \ ' collapse = true;\n' \ ' }\n' \ ' else if (option == "~COLLAPSE")\n' \ ' {\n' \ ' collapse = false;\n' \ ' }\n' \ ' else if (option == "SITEKEY" && typeof value != "undefined")\n' \ ' {\n' \ ' sitekeys = value;\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return new InvalidFilter(origText, "Unknown option " + option.toLowerCase());\n' \ ' }\n' \ ' }\n' \ ' }\n' \ ' if (!blocking && (contentType == null || contentType & RegExpFilter.typeMap.DOCUMENT) && (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text))\n' \ ' {\n' \ ' if (contentType == null)\n' \ ' {\n' \ ' contentType = RegExpFilter.prototype.contentType;\n' \ ' }\n' \ ' contentType &= ~RegExpFilter.typeMap.DOCUMENT;\n' \ ' }\n' \ ' try\n' \ ' {\n' \ ' if (blocking)\n' \ ' {\n' \ ' return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys);\n' \ ' }\n' \ ' }\n' \ ' catch (e)\n' \ ' {\n' \ ' return new InvalidFilter(origText, e);\n' \ ' }\n' \ '};\n' \ 'RegExpFilter.typeMap = {\n' \ ' OTHER: 1,\n' \ ' SCRIPT: 2,\n' \ ' IMAGE: 4,\n' \ ' STYLESHEET: 8,\n' \ ' OBJECT: 16,\n' \ ' SUBDOCUMENT: 32,\n' \ ' DOCUMENT: 64,\n' \ ' XBL: 1,\n' \ ' PING: 1,\n' \ ' XMLHTTPREQUEST: 2048,\n' \ ' OBJECT_SUBREQUEST: 4096,\n' \ ' DTD: 1,\n' \ ' MEDIA: 16384,\n' \ ' FONT: 32768,\n' \ ' BACKGROUND: 4,\n' \ ' POPUP: 268435456,\n' \ ' ELEMHIDE: 1073741824\n' \ '};\n' \ 'RegExpFilter.prototype.contentType &= ~ (RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.POPUP);\n' \ '\n' \ 'function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse)\n' \ '{\n' \ ' RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);\n' \ ' this.collapse = collapse;\n' \ '}\n' \ 'extend(BlockingFilter, RegExpFilter, {\n' \ ' collapse: null\n' \ '});\n' \ '\n' \ 'function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys)\n' \ '{\n' \ ' RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys);\n' \ '}\n' \ 'extend(WhitelistFilter, RegExpFilter, {\n' \ '});\n' \ '\n' \ 'function Matcher()\n' \ '{\n' \ ' this.clear();\n' \ '}\n' \ 'Matcher.prototype = {\n' \ ' filterByKeyword: null,\n' \ ' keywordByFilter: null,\n' \ ' clear: function()\n' \ ' {\n' \ ' this.filterByKeyword = createDict();\n' \ ' this.keywordByFilter = createDict();\n' \ ' },\n' \ ' add: function(filter)\n' \ ' {\n' \ ' if (filter.text in this.keywordByFilter)\n' \ ' {\n' \ ' return;\n' \ ' }\n' \ ' var keyword = this.findKeyword(filter);\n' \ ' var oldEntry = this.filterByKeyword[keyword];\n' \ ' if (typeof oldEntry == "undefined")\n' \ ' {\n' \ ' this.filterByKeyword[keyword] = filter;\n' \ ' }\n' \ ' else if (oldEntry.length == 1)\n' \ ' {\n' \ ' this.filterByKeyword[keyword] = [oldEntry, filter];\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' oldEntry.push(filter);\n' \ ' }\n' \ ' this.keywordByFilter[filter.text] = keyword;\n' \ ' },\n' \ ' remove: function(filter)\n' \ ' {\n' \ ' if (!(filter.text in this.keywordByFilter))\n' \ ' {\n' \ ' return;\n' \ ' }\n' \ ' var keyword = this.keywordByFilter[filter.text];\n' \ ' var list = this.filterByKeyword[keyword];\n' \ ' if (list.length <= 1)\n' \ ' {\n' \ ' delete this.filterByKeyword[keyword];\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' var index = list.indexOf(filter);\n' \ ' if (index >= 0)\n' \ ' {\n' \ ' list.splice(index, 1);\n' \ ' if (list.length == 1)\n' \ ' {\n' \ ' this.filterByKeyword[keyword] = list[0];\n' \ ' }\n' \ ' }\n' \ ' }\n' \ ' delete this.keywordByFilter[filter.text];\n' \ ' },\n' \ ' findKeyword: function(filter)\n' \ ' {\n' \ ' var result = "";\n' \ ' var text = filter.text;\n' \ ' if (Filter.regexpRegExp.test(text))\n' \ ' {\n' \ ' return result;\n' \ ' }\n' \ ' var match = Filter.optionsRegExp.exec(text);\n' \ ' if (match)\n' \ ' {\n' \ ' text = match.input.substr(0, match.index);\n' \ ' }\n' \ ' if (text.substr(0, 2) == "@@")\n' \ ' {\n' \ ' text = text.substr(2);\n' \ ' }\n' \ ' var candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g);\n' \ ' if (!candidates)\n' \ ' {\n' \ ' return result;\n' \ ' }\n' \ ' var hash = this.filterByKeyword;\n' \ ' var resultCount = 16777215;\n' \ ' var resultLength = 0;\n' \ ' for (var i = 0, l = candidates.length; i < l; i++)\n' \ ' {\n' \ ' var candidate = candidates[i].substr(1);\n' \ ' var count = candidate in hash ? hash[candidate].length : 0;\n' \ ' if (count < resultCount || count == resultCount && candidate.length > resultLength)\n' \ ' {\n' \ ' result = candidate;\n' \ ' resultCount = count;\n' \ ' resultLength = candidate.length;\n' \ ' }\n' \ ' }\n' \ ' return result;\n' \ ' },\n' \ ' hasFilter: function(filter)\n' \ ' {\n' \ ' return filter.text in this.keywordByFilter;\n' \ ' },\n' \ ' getKeywordForFilter: function(filter)\n' \ ' {\n' \ ' if (filter.text in this.keywordByFilter)\n' \ ' {\n' \ ' return this.keywordByFilter[filter.text];\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return null;\n' \ ' }\n' \ ' },\n' \ ' _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty, sitekey)\n' \ ' {\n' \ ' var list = this.filterByKeyword[keyword];\n' \ ' for (var i = 0; i < list.length; i++)\n' \ ' {\n' \ ' var filter = list[i];\n' \ ' if (filter == "#this")\n' \ ' {\n' \ ' filter = list;\n' \ ' }\n' \ ' if (filter.matches(location, contentType, docDomain, thirdParty, sitekey))\n' \ ' {\n' \ ' return filter;\n' \ ' }\n' \ ' }\n' \ ' return null;\n' \ ' },\n' \ ' matchesAny: function(location, contentType, docDomain, thirdParty, sitekey)\n' \ ' {\n' \ ' var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);\n' \ ' if (candidates === null)\n' \ ' {\n' \ ' candidates = [];\n' \ ' }\n' \ ' candidates.push("");\n' \ ' for (var i = 0, l = candidates.length; i < l; i++)\n' \ ' {\n' \ ' var substr = candidates[i];\n' \ ' if (substr in this.filterByKeyword)\n' \ ' {\n' \ ' var result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);\n' \ ' if (result)\n' \ ' {\n' \ ' return result;\n' \ ' }\n' \ ' }\n' \ ' }\n' \ ' return null;\n' \ ' }\n' \ '};\n' \ '\n' \ 'function CombinedMatcher()\n' \ '{\n' \ ' this.blacklist = new Matcher();\n' \ ' this.whitelist = new Matcher();\n' \ ' this.resultCache = createDict();\n' \ '}\n' \ 'CombinedMatcher.maxCacheEntries = 1000;\n' \ 'CombinedMatcher.prototype = {\n' \ ' blacklist: null,\n' \ ' whitelist: null,\n' \ ' resultCache: null,\n' \ ' cacheEntries: 0,\n' \ ' clear: function()\n' \ ' {\n' \ ' this.blacklist.clear();\n' \ ' this.whitelist.clear();\n' \ ' this.resultCache = createDict();\n' \ ' this.cacheEntries = 0;\n' \ ' },\n' \ ' add: function(filter)\n' \ ' {\n' \ ' if (filter instanceof WhitelistFilter)\n' \ ' {\n' \ ' this.whitelist.add(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' this.blacklist.add(filter);\n' \ ' }\n' \ ' if (this.cacheEntries > 0)\n' \ ' {\n' \ ' this.resultCache = createDict();\n' \ ' this.cacheEntries = 0;\n' \ ' }\n' \ ' },\n' \ ' remove: function(filter)\n' \ ' {\n' \ ' if (filter instanceof WhitelistFilter)\n' \ ' {\n' \ ' this.whitelist.remove(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' this.blacklist.remove(filter);\n' \ ' }\n' \ ' if (this.cacheEntries > 0)\n' \ ' {\n' \ ' this.resultCache = createDict();\n' \ ' this.cacheEntries = 0;\n' \ ' }\n' \ ' },\n' \ ' findKeyword: function(filter)\n' \ ' {\n' \ ' if (filter instanceof WhitelistFilter)\n' \ ' {\n' \ ' return this.whitelist.findKeyword(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return this.blacklist.findKeyword(filter);\n' \ ' }\n' \ ' },\n' \ ' hasFilter: function(filter)\n' \ ' {\n' \ ' if (filter instanceof WhitelistFilter)\n' \ ' {\n' \ ' return this.whitelist.hasFilter(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return this.blacklist.hasFilter(filter);\n' \ ' }\n' \ ' },\n' \ ' getKeywordForFilter: function(filter)\n' \ ' {\n' \ ' if (filter instanceof WhitelistFilter)\n' \ ' {\n' \ ' return this.whitelist.getKeywordForFilter(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return this.blacklist.getKeywordForFilter(filter);\n' \ ' }\n' \ ' },\n' \ ' isSlowFilter: function(filter)\n' \ ' {\n' \ ' var matcher = filter instanceof WhitelistFilter ? this.whitelist : this.blacklist;\n' \ ' if (matcher.hasFilter(filter))\n' \ ' {\n' \ ' return !matcher.getKeywordForFilter(filter);\n' \ ' }\n' \ ' else\n' \ ' {\n' \ ' return !matcher.findKeyword(filter);\n' \ ' }\n' \ ' },\n' \ ' matchesAnyInternal: function(location, contentType, docDomain, thirdParty, sitekey)\n' \ ' {\n' \ ' var candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);\n' \ ' if (candidates === null)\n' \ ' {\n' \ ' candidates = [];\n' \ ' }\n' \ ' candidates.push("");\n' \ ' var blacklistHit = null;\n' \ ' for (var i = 0, l = candidates.length; i < l; i++)\n' \ ' {\n' \ ' var substr = candidates[i];\n' \ ' if (substr in this.whitelist.filterByKeyword)\n' \ ' {\n' \ ' var result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);\n' \ ' if (result)\n' \ ' {\n' \ ' return result;\n' \ ' }\n' \ ' }\n' \ ' if (substr in this.blacklist.filterByKeyword && blacklistHit === null)\n' \ ' {\n' \ ' blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey);\n' \ ' }\n' \ ' }\n' \ ' return blacklistHit;\n' \ ' },\n' \ ' matchesAny: function(location, docDomain)\n' \ ' {\n' \ ' var key = location + " " + docDomain + " ";\n' \ ' if (key in this.resultCache)\n' \ ' {\n' \ ' return this.resultCache[key];\n' \ ' }\n' \ ' var result = this.matchesAnyInternal(location, 0, docDomain, null, null);\n' \ ' if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)\n' \ ' {\n' \ ' this.resultCache = createDict();\n' \ ' this.cacheEntries = 0;\n' \ ' }\n' \ ' this.resultCache[key] = result;\n' \ ' this.cacheEntries++;\n' \ ' return result;\n' \ ' }\n' \ '};\n' \ 'var defaultMatcher = new CombinedMatcher();\n' \ '\n' \ 'var direct = \'DIRECT;\';\n' \ '\n' \ 'for (var i = 0; i < rules.length; i++) {\n' \ ' defaultMatcher.add(Filter.fromText(rules[i]));\n' \ '}\n' \ '\n' \ 'function FindProxyForURL(url, host) {\n' \ ' if (defaultMatcher.matchesAny(url, host) instanceof BlockingFilter) {\n' \ ' return proxy;\n' \ ' }\n' \ ' return direct;\n' \ '}\n' return pacScript if __name__ == '__main__': print(create())