var direct = "__DIRECT__";
if (direct == "__DIR" + "ECT__") direct = "DIRECT;";
var wall_proxy = function(){ return "__PROXY__"; };
var wall_v6_proxy = function(){ return "__PROXY__"; };
var nowall_proxy = function(){ return direct; };
var ip_proxy = function(){ return nowall_proxy(); };
var ipv6_proxy = function(){ return nowall_proxy(); };
var rules = [
"||google",
"||facebook",
"||nexon",
"||nexoncdn",
"||maplemaps",
"||maplescouter",
"||nxl.log.nexon.io",
"||nxl.nxfs.nexon.com",
"||o878075.ingest.sentry.io",
"||player.twitch.tv",
"||pre-nxl.nxfs.nexon.com",
"||web.nxfs.nexon.com",
"||www.facebook.com",
"||www.google-analytics.com",
"||www.nexon.com",
"||mapleutils.com",
"||seraph.game",
"||mapleranks.com",
"||11776020.fls.doubleclick.net",
"||alb.reddit.com",
"||steamserver.net",
"||steam-chat.com",
"||analytics.tiktok.com",
"||bs.serving-sys.com",
"||cdn.cookielaw.org",
"||cdn.gsght.com",
"||connect.facebook.net",
"||g.nexonstatic.com",
"||www.redditstatic.com",
"||www.googletagmanager.com",
"||tr.snapchat.com",
"||t.co",
"||static.ads-twitter.com",
"||secure-ds.serving-sys.com",
"||sc-static.net",
"||privacyportal.onetrust.com",
"||pixel.tapad.com",
"||match.adsrvr.org",
"||lm.serving-sys.com",
"||insight.adsrvr.org",
"||gocashgamecard.com",
"||discord.com",
"||discordapp.net",
"||discord.gg",
"||ytimg.com",
"||googleusercontent.com",
"||raw.githubusercontent.com",
"||ssl.gstatic.com",
"||status.discord.com",
"||googleapis.com",
"||www.gravatar.com",
"||www.gstatic.com",
"||beanfun.com",
"||steampowered.com",
"||steamcommunity.com",
"||ipip",
"||google.com",
"||analytics.com",
"||nexon.io",
"||cookielaw.org",
"||gsght.com",
"||googleapis.com",
"||facebook.net",
"||gstatic.com",
"||onetrust.com",
"||googleusercontent.com",
"||nexon.net",
"||nexon.com",
"||sentry.io",
"||digicert.com",
"||pki.goog",
"||twitch.tv",
"||nxfs.nexon.com",
"||lencr.org",
"||githubusercontent.com",
"||recaptcha.net",
"||ytimg.com",
"||doubleclick.net",
"||facebook.com",
"||google-analytics.com",
"||googletagmanager.com",
"||battle.net",
"||battlenet.com.cn",
"||blizzard.com"
];
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.charAt(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]).charAt(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.charAt(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.charAt(0) == "/" && regexpSource.charAt(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.charAt(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();
for (var i = 0; i < rules.length; i++) {
	defaultMatcher.add(Filter.fromText(rules[i]));
}
var subnetIpRangeList = [
0,1,
167772160,184549376,	//10.0.0.0/8
2886729728,2887778304,	//172.16.0.0/12
3232235520,3232301056,	//192.168.0.0/16
2130706432,2130706688	//127.0.0.0/24
];
function convertAddress(ipchars) {
	var bytes = ipchars.split('.');
	var result = (bytes[0] << 24) |
	(bytes[1] << 16) |
	(bytes[2] << 8) |
	(bytes[3]);
	return result >>> 0;
}
function check_ipv4(host) {
	var re_ipv4 = /^\d+\.\d+\.\d+\.\d+$/g;
	if (re_ipv4.test(host)) {
		return true;
	}
}
function check_ipv6(host) {
	var re_ipv6 = /^\[?([a-fA-F0-9]{0,4}\:){1,7}[a-fA-F0-9]{0,4}\]?$/g;
	if (re_ipv6.test(host)) {
		return true;
	}
}
function check_ipv6_dns(dnsstr) {
	var re_ipv6 = /([a-fA-F0-9]{0,4}\:){1,7}[a-fA-F0-9]{0,4}(%[0-9]+)?/g;
	if (re_ipv6.test(dnsstr)) {
		return true;
	}
}
function isInSubnetRange(ipRange, intIp) {
	for ( var i = 0; i < 10; i += 2 ) {
		if ( ipRange[i] <= intIp && intIp < ipRange[i+1] )
			return true;
	}
}
function getProxyFromIP(strIp) {
	var intIp = convertAddress(strIp);
	if ( isInSubnetRange(subnetIpRangeList, intIp) ) {
		return direct;
	}
	return ip_proxy();
}
function FindProxyForURL(url, host) {
	if ( isPlainHostName(host) === true ) {
		return direct;
	}
	if (defaultMatcher.matchesAny(url, host) instanceof BlockingFilter) {
		return wall_proxy();
	}
	if ( check_ipv4(host) === true ) {
		return getProxyFromIP(host);
	}
	return direct;
}